Split pdfium_unittests sources.

Move foo_unittest.cpp to the same BUILD.gn file as foo.cpp.
Set up dependencies to make pdfium_unittests pass gn check.

Change-Id: Id9f649d5d0c76fe4254f3887778516abb75fcbce
Reviewed-on: https://pdfium-review.googlesource.com/c/43995
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/.gn b/.gn
index 5f7540a..064cf5d 100644
--- a/.gn
+++ b/.gn
@@ -18,6 +18,7 @@
 
 check_targets = [
   ":pdfium",
+  ":pdfium_unittests",
   "//core/*",
   "//fpdfsdk/*",
   "//fxbarcode/*",
diff --git a/BUILD.gn b/BUILD.gn
index 14cf737..fc61dce 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -210,149 +210,75 @@
   "//:gn_visibility",
 ]
 
-test("pdfium_unittests") {
+group("pdfium_unittest_deps") {
   testonly = true
-  sources = [
-    "core/fdrm/fx_crypt_unittest.cpp",
-    "core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp",
-    "core/fpdfapi/font/cpdf_cmapparser_unittest.cpp",
-    "core/fpdfapi/font/cpdf_tounicodemap_unittest.cpp",
-    "core/fpdfapi/page/cpdf_devicecs_unittest.cpp",
-    "core/fpdfapi/page/cpdf_pageobjectholder_unittest.cpp",
-    "core/fpdfapi/page/cpdf_psengine_unittest.cpp",
-    "core/fpdfapi/page/cpdf_streamcontentparser_unittest.cpp",
-    "core/fpdfapi/page/cpdf_streamparser_unittest.cpp",
-    "core/fpdfapi/parser/cpdf_array_unittest.cpp",
-    "core/fpdfapi/parser/cpdf_cross_ref_avail_unittest.cpp",
-    "core/fpdfapi/parser/cpdf_document_unittest.cpp",
-    "core/fpdfapi/parser/cpdf_hint_tables_unittest.cpp",
-    "core/fpdfapi/parser/cpdf_indirect_object_holder_unittest.cpp",
-    "core/fpdfapi/parser/cpdf_object_avail_unittest.cpp",
-    "core/fpdfapi/parser/cpdf_object_unittest.cpp",
-    "core/fpdfapi/parser/cpdf_object_walker_unittest.cpp",
-    "core/fpdfapi/parser/cpdf_page_object_avail_unittest.cpp",
-    "core/fpdfapi/parser/cpdf_parser_unittest.cpp",
-    "core/fpdfapi/parser/cpdf_read_validator_unittest.cpp",
-    "core/fpdfapi/parser/cpdf_simple_parser_unittest.cpp",
-    "core/fpdfapi/parser/cpdf_stream_acc_unittest.cpp",
-    "core/fpdfapi/parser/cpdf_syntax_parser_unittest.cpp",
-    "core/fpdfapi/parser/fpdf_parser_decode_unittest.cpp",
-    "core/fpdfapi/parser/fpdf_parser_utility_unittest.cpp",
-    "core/fpdfdoc/cpdf_defaultappearance_unittest.cpp",
-    "core/fpdfdoc/cpdf_dest_unittest.cpp",
-    "core/fpdfdoc/cpdf_filespec_unittest.cpp",
-    "core/fpdfdoc/cpdf_formfield_unittest.cpp",
-    "core/fpdfdoc/cpdf_metadata_unittest.cpp",
-    "core/fpdfdoc/cpdf_nametree_unittest.cpp",
-    "core/fpdftext/cpdf_linkextract_unittest.cpp",
-    "core/fxcodec/codec/fx_codec_a85_unittest.cpp",
-    "core/fxcodec/codec/fx_codec_jpx_unittest.cpp",
-    "core/fxcodec/codec/fx_codec_rle_unittest.cpp",
-    "core/fxcodec/jbig2/JBig2_BitStream_unittest.cpp",
-    "core/fxcodec/jbig2/JBig2_Image_unittest.cpp",
-    "core/fxcrt/autorestorer_unittest.cpp",
-    "core/fxcrt/bytestring_unittest.cpp",
-    "core/fxcrt/cfx_bitstream_unittest.cpp",
-    "core/fxcrt/fx_bidi_unittest.cpp",
-    "core/fxcrt/fx_coordinates_unittest.cpp",
-    "core/fxcrt/fx_extension_unittest.cpp",
-    "core/fxcrt/fx_memory_unittest.cpp",
-    "core/fxcrt/fx_number_unittest.cpp",
-    "core/fxcrt/fx_random_unittest.cpp",
-    "core/fxcrt/fx_string_unittest.cpp",
-    "core/fxcrt/fx_system_unittest.cpp",
-    "core/fxcrt/maybe_owned_unittest.cpp",
-    "core/fxcrt/observable_unittest.cpp",
-    "core/fxcrt/pdfium_span_unittest.cpp",
-    "core/fxcrt/retain_ptr_unittest.cpp",
-    "core/fxcrt/shared_copy_on_write_unittest.cpp",
-    "core/fxcrt/string_pool_template_unittest.cpp",
-    "core/fxcrt/unowned_ptr_unittest.cpp",
-    "core/fxcrt/weak_ptr_unittest.cpp",
-    "core/fxcrt/widestring_unittest.cpp",
-    "core/fxcrt/xml/cfx_xmlchardata_unittest.cpp",
-    "core/fxcrt/xml/cfx_xmldocument_unittest.cpp",
-    "core/fxcrt/xml/cfx_xmlelement_unittest.cpp",
-    "core/fxcrt/xml/cfx_xmlinstruction_unittest.cpp",
-    "core/fxcrt/xml/cfx_xmlnode_unittest.cpp",
-    "core/fxcrt/xml/cfx_xmlparser_unittest.cpp",
-    "core/fxcrt/xml/cfx_xmltext_unittest.cpp",
-    "core/fxge/dib/cfx_dibitmap_unittest.cpp",
-    "core/fxge/dib/cstretchengine_unittest.cpp",
-    "fpdfsdk/fpdf_catalog_unittest.cpp",
-    "fpdfsdk/fpdf_doc_unittest.cpp",
-    "fpdfsdk/fpdf_editimg_unittest.cpp",
-    "testing/pseudo_retainable.h",
-    "testing/unit_test_main.cpp",
-  ]
-  deps = [
-    ":pdfium",
+  public_deps = [
+    "core/fxcrt",
     "testing/:test_support",
     "//testing/gmock",
     "//testing/gtest",
   ]
-  include_dirs = []
+  visibility += [
+    "core/*",
+    "fpdfsdk/*",
+    "fxbarcode/*",
+    "fxjs/*",
+    "xfa/*",
+  ]
+}
+
+test("pdfium_unittests") {
+  testonly = true
+  sources = [
+    "testing/unit_test_main.cpp",
+  ]
+  deps = [
+    "core/fdrm:unittests",
+    "core/fpdfapi/edit:unittests",
+    "core/fpdfapi/font:unittests",
+    "core/fpdfapi/page:unittests",
+    "core/fpdfapi/parser:unittests",
+    "core/fpdfdoc:unittests",
+    "core/fpdftext:unittests",
+    "core/fxcodec:unittests",
+    "core/fxcrt",
+    "core/fxcrt:unittests",
+    "core/fxge",
+    "core/fxge:unittests",
+    "fpdfsdk:unittests",
+    "testing/:test_support",
+    "//testing/gmock",
+    "//testing/gtest",
+  ]
+  configs += [ ":pdfium_core_config" ]
   if (pdf_enable_xfa) {
-    sources += [
-      "core/fxcrt/cfx_seekablemultistream_unittest.cpp",
-      "core/fxcrt/css/cfx_cssdeclaration_unittest.cpp",
-      "core/fxcrt/css/cfx_cssstylesheet_unittest.cpp",
-      "core/fxcrt/css/cfx_cssvaluelistparser_unittest.cpp",
-      "fxbarcode/oned/BC_OnedCodaBarWriter_unittest.cpp",
-      "fxbarcode/oned/BC_OnedCode128Writer_unittest.cpp",
-      "fxbarcode/oned/BC_OnedCode39Writer_unittest.cpp",
-      "fxbarcode/oned/BC_OnedEAN13Writer_unittest.cpp",
-      "fxbarcode/oned/BC_OnedEAN8Writer_unittest.cpp",
-      "fxbarcode/oned/BC_OnedUPCAWriter_unittest.cpp",
-      "fxbarcode/pdf417/BC_PDF417HighLevelEncoder_unittest.cpp",
-      "xfa/fde/cfde_texteditengine_unittest.cpp",
-      "xfa/fgas/crt/cfgas_formatstring_unittest.cpp",
-      "xfa/fgas/layout/cfx_rtfbreak_unittest.cpp",
-      "xfa/fgas/layout/cfx_txtbreak_unittest.cpp",
-      "xfa/fwl/cfx_barcode_unittest.cpp",
-      "xfa/fxfa/cxfa_ffbarcode_unittest.cpp",
-      "xfa/fxfa/cxfa_textparser_unittest.cpp",
-      "xfa/fxfa/fm2js/cxfa_fmexpression_unittest.cpp",
-      "xfa/fxfa/fm2js/cxfa_fmlexer_unittest.cpp",
-      "xfa/fxfa/fm2js/cxfa_fmparser_unittest.cpp",
-      "xfa/fxfa/fm2js/cxfa_fmsimpleexpression_unittest.cpp",
-      "xfa/fxfa/parser/cxfa_document_parser_unittest.cpp",
-      "xfa/fxfa/parser/cxfa_localevalue_unittest.cpp",
-      "xfa/fxfa/parser/cxfa_node_unittest.cpp",
-      "xfa/fxfa/parser/cxfa_nodeiteratortemplate_unittest.cpp",
-      "xfa/fxfa/parser/cxfa_xmllocale_unittest.cpp",
-      "xfa/fxfa/parser/xfa_utils_unittest.cpp",
+    deps += [
+      "fxbarcode:unittests",
+      "xfa/fde:unittests",
+      "xfa/fgas",
+      "xfa/fgas:unittests",
+      "xfa/fwl:unittests",
+      "xfa/fxfa:unittests",
+      "xfa/fxfa/fm2js:unittests",
+      "xfa/fxfa/parser:unittests",
     ]
-    if (pdf_enable_xfa_gif) {
-      sources += [
-        "core/fxcodec/gif/cfx_gifcontext_unittest.cpp",
-        "core/fxcodec/gif/cfx_lzwdecompressor_unittest.cpp",
-      ]
-    }
   }
+
+  # TODO(thestig): Should this be an embeddertest?
   if (pdf_use_skia || pdf_use_skia_paths) {
     sources += [ "core/fxge/skia/fx_skia_device_unittest.cpp" ]
     deps += [ "//skia" ]
   }
   if (pdf_enable_v8) {
-    sources += [
-      "fxjs/cfx_v8_unittest.cpp",
-      "fxjs/cfx_v8_unittest.h",
-      "fxjs/cfxjs_engine_unittest.cpp",
-      "fxjs/cjs_publicmethods_unittest.cpp",
-      "fxjs/cjs_util_unittest.cpp",
-    ]
-    deps += [ "fxjs" ]
     configs += [ "//v8:external_startup_data" ]
+    deps += [
+      "fxjs:unittests",
+      "//v8",
+    ]
   }
-  configs += [ ":pdfium_core_config" ]
   if (is_android) {
     use_raw_android_executable = true
   }
-  if (is_clang) {
-    # Suppress no override warning for overridden functions.
-    cflags = [ "-Wno-inconsistent-missing-override" ]
-  }
 }
 
 test("pdfium_embeddertests") {
diff --git a/core/fdrm/BUILD.gn b/core/fdrm/BUILD.gn
index 7a083ff..ce70689 100644
--- a/core/fdrm/BUILD.gn
+++ b/core/fdrm/BUILD.gn
@@ -4,6 +4,7 @@
 
 import("//build/config/jumbo.gni")
 import("../../pdfium.gni")
+import("../../testing/test.gni")
 
 jumbo_source_set("fdrm") {
   sources = [
@@ -18,3 +19,13 @@
   ]
   visibility = [ "../../*" ]
 }
+
+pdfium_unittest_source_set("unittests") {
+  sources = [
+    "fx_crypt_unittest.cpp",
+  ]
+  deps = [
+    ":fdrm",
+  ]
+  pdfium_root_dir = "../../"
+}
diff --git a/core/fpdfapi/edit/BUILD.gn b/core/fpdfapi/edit/BUILD.gn
index de1a404..6c88522 100644
--- a/core/fpdfapi/edit/BUILD.gn
+++ b/core/fpdfapi/edit/BUILD.gn
@@ -4,6 +4,7 @@
 
 import("//build/config/jumbo.gni")
 import("../../../pdfium.gni")
+import("../../../testing/test.gni")
 
 jumbo_source_set("edit") {
   sources = [
@@ -31,3 +32,17 @@
   allow_circular_includes_from = [ "../parser" ]
   visibility = [ "../../../*" ]
 }
+
+pdfium_unittest_source_set("unittests") {
+  sources = [
+    "cpdf_pagecontentgenerator_unittest.cpp",
+  ]
+  deps = [
+    ":edit",
+    "../",
+    "../font",
+    "../page",
+    "../parser",
+  ]
+  pdfium_root_dir = "../../../"
+}
diff --git a/core/fpdfapi/font/BUILD.gn b/core/fpdfapi/font/BUILD.gn
index a8f8619..a6f9705 100644
--- a/core/fpdfapi/font/BUILD.gn
+++ b/core/fpdfapi/font/BUILD.gn
@@ -4,6 +4,7 @@
 
 import("//build/config/jumbo.gni")
 import("../../../pdfium.gni")
+import("../../../testing/test.gni")
 
 jumbo_source_set("font") {
   sources = [
@@ -54,3 +55,14 @@
   ]
   visibility = [ "../../../*" ]
 }
+
+pdfium_unittest_source_set("unittests") {
+  sources = [
+    "cpdf_cmapparser_unittest.cpp",
+    "cpdf_tounicodemap_unittest.cpp",
+  ]
+  deps = [
+    ":font",
+  ]
+  pdfium_root_dir = "../../../"
+}
diff --git a/core/fpdfapi/page/BUILD.gn b/core/fpdfapi/page/BUILD.gn
index 5df39f2..9c57fce 100644
--- a/core/fpdfapi/page/BUILD.gn
+++ b/core/fpdfapi/page/BUILD.gn
@@ -4,6 +4,7 @@
 
 import("//build/config/jumbo.gni")
 import("../../../pdfium.gni")
+import("../../../testing/test.gni")
 
 jumbo_source_set("page") {
   sources = [
@@ -111,3 +112,17 @@
   }
   visibility = [ "../../../*" ]
 }
+
+pdfium_unittest_source_set("unittests") {
+  sources = [
+    "cpdf_devicecs_unittest.cpp",
+    "cpdf_pageobjectholder_unittest.cpp",
+    "cpdf_psengine_unittest.cpp",
+    "cpdf_streamcontentparser_unittest.cpp",
+    "cpdf_streamparser_unittest.cpp",
+  ]
+  deps = [
+    ":page",
+  ]
+  pdfium_root_dir = "../../../"
+}
diff --git a/core/fpdfapi/parser/BUILD.gn b/core/fpdfapi/parser/BUILD.gn
index 64306df..52de29d 100644
--- a/core/fpdfapi/parser/BUILD.gn
+++ b/core/fpdfapi/parser/BUILD.gn
@@ -4,6 +4,7 @@
 
 import("//build/config/jumbo.gni")
 import("../../../pdfium.gni")
+import("../../../testing/test.gni")
 
 jumbo_source_set("parser") {
   sources = [
@@ -83,3 +84,34 @@
   ]
   visibility = [ "../../../*" ]
 }
+
+pdfium_unittest_source_set("unittests") {
+  sources = [
+    "cpdf_array_unittest.cpp",
+    "cpdf_cross_ref_avail_unittest.cpp",
+    "cpdf_document_unittest.cpp",
+    "cpdf_hint_tables_unittest.cpp",
+    "cpdf_indirect_object_holder_unittest.cpp",
+    "cpdf_object_avail_unittest.cpp",
+    "cpdf_object_unittest.cpp",
+    "cpdf_object_walker_unittest.cpp",
+    "cpdf_page_object_avail_unittest.cpp",
+    "cpdf_parser_unittest.cpp",
+    "cpdf_read_validator_unittest.cpp",
+    "cpdf_simple_parser_unittest.cpp",
+    "cpdf_stream_acc_unittest.cpp",
+    "cpdf_syntax_parser_unittest.cpp",
+    "fpdf_parser_decode_unittest.cpp",
+    "fpdf_parser_utility_unittest.cpp",
+  ]
+  deps = [
+    ":parser",
+    "../",
+  ]
+  pdfium_root_dir = "../../../"
+
+  if (is_clang) {
+    # Suppress no override warning for overridden functions.
+    cflags = [ "-Wno-inconsistent-missing-override" ]
+  }
+}
diff --git a/core/fpdfdoc/BUILD.gn b/core/fpdfdoc/BUILD.gn
index 411d26a..e243823 100644
--- a/core/fpdfdoc/BUILD.gn
+++ b/core/fpdfdoc/BUILD.gn
@@ -4,6 +4,7 @@
 
 import("//build/config/jumbo.gni")
 import("../../pdfium.gni")
+import("../../testing/test.gni")
 
 jumbo_source_set("fpdfdoc") {
   sources = [
@@ -99,3 +100,19 @@
   ]
   visibility = [ "../../*" ]
 }
+
+pdfium_unittest_source_set("unittests") {
+  sources = [
+    "cpdf_defaultappearance_unittest.cpp",
+    "cpdf_dest_unittest.cpp",
+    "cpdf_filespec_unittest.cpp",
+    "cpdf_formfield_unittest.cpp",
+    "cpdf_metadata_unittest.cpp",
+    "cpdf_nametree_unittest.cpp",
+  ]
+  deps = [
+    ":fpdfdoc",
+    "../fpdfapi/parser",
+  ]
+  pdfium_root_dir = "../../"
+}
diff --git a/core/fpdftext/BUILD.gn b/core/fpdftext/BUILD.gn
index 1319c62..2192df6 100644
--- a/core/fpdftext/BUILD.gn
+++ b/core/fpdftext/BUILD.gn
@@ -4,6 +4,7 @@
 
 import("//build/config/jumbo.gni")
 import("../../pdfium.gni")
+import("../../testing/test.gni")
 
 jumbo_source_set("fpdftext") {
   sources = [
@@ -25,3 +26,13 @@
   ]
   visibility = [ "../../*" ]
 }
+
+pdfium_unittest_source_set("unittests") {
+  sources = [
+    "cpdf_linkextract_unittest.cpp",
+  ]
+  deps = [
+    ":fpdftext",
+  ]
+  pdfium_root_dir = "../../"
+}
diff --git a/core/fxcodec/BUILD.gn b/core/fxcodec/BUILD.gn
index 4c06d55..1c68956 100644
--- a/core/fxcodec/BUILD.gn
+++ b/core/fxcodec/BUILD.gn
@@ -4,6 +4,7 @@
 
 import("//build/config/jumbo.gni")
 import("../../pdfium.gni")
+import("../../testing/test.gni")
 
 jumbo_source_set("fxcodec") {
   sources = [
@@ -124,3 +125,25 @@
   }
   visibility = [ "../../*" ]
 }
+
+pdfium_unittest_source_set("unittests") {
+  sources = [
+    "codec/fx_codec_a85_unittest.cpp",
+    "codec/fx_codec_jpx_unittest.cpp",
+    "codec/fx_codec_rle_unittest.cpp",
+    "jbig2/JBig2_BitStream_unittest.cpp",
+    "jbig2/JBig2_Image_unittest.cpp",
+  ]
+  deps = [
+    ":fxcodec",
+    "../fpdfapi/parser",
+  ]
+  pdfium_root_dir = "../../"
+
+  if (pdf_enable_xfa && pdf_enable_xfa_gif) {
+    sources += [
+      "gif/cfx_gifcontext_unittest.cpp",
+      "gif/cfx_lzwdecompressor_unittest.cpp",
+    ]
+  }
+}
diff --git a/core/fxcrt/BUILD.gn b/core/fxcrt/BUILD.gn
index 3a38520..d489dea 100644
--- a/core/fxcrt/BUILD.gn
+++ b/core/fxcrt/BUILD.gn
@@ -4,6 +4,7 @@
 
 import("//build/config/jumbo.gni")
 import("../../pdfium.gni")
+import("../../testing/test.gni")
 
 jumbo_source_set("fxcrt") {
   sources = [
@@ -144,3 +145,51 @@
     visibility = [ "../../*" ]
   }
 }
+
+pdfium_unittest_source_set("unittests") {
+  sources = [
+    "autorestorer_unittest.cpp",
+    "bytestring_unittest.cpp",
+    "cfx_bitstream_unittest.cpp",
+    "fx_bidi_unittest.cpp",
+    "fx_coordinates_unittest.cpp",
+    "fx_extension_unittest.cpp",
+    "fx_memory_unittest.cpp",
+    "fx_number_unittest.cpp",
+    "fx_random_unittest.cpp",
+    "fx_string_unittest.cpp",
+    "fx_system_unittest.cpp",
+    "maybe_owned_unittest.cpp",
+    "observable_unittest.cpp",
+    "pdfium_span_unittest.cpp",
+    "retain_ptr_unittest.cpp",
+    "shared_copy_on_write_unittest.cpp",
+    "string_pool_template_unittest.cpp",
+    "unowned_ptr_unittest.cpp",
+    "weak_ptr_unittest.cpp",
+    "widestring_unittest.cpp",
+    "xml/cfx_xmlchardata_unittest.cpp",
+    "xml/cfx_xmldocument_unittest.cpp",
+    "xml/cfx_xmlelement_unittest.cpp",
+    "xml/cfx_xmlinstruction_unittest.cpp",
+    "xml/cfx_xmlnode_unittest.cpp",
+    "xml/cfx_xmlparser_unittest.cpp",
+    "xml/cfx_xmltext_unittest.cpp",
+  ]
+  deps = []
+  pdfium_root_dir = "../../"
+
+  if (pdf_enable_xfa) {
+    sources += [
+      "cfx_seekablemultistream_unittest.cpp",
+      "css/cfx_cssdeclaration_unittest.cpp",
+      "css/cfx_cssstylesheet_unittest.cpp",
+      "css/cfx_cssvaluelistparser_unittest.cpp",
+    ]
+    deps += [
+      ":seekablemultistream",
+      "../fpdfapi/parser",
+      "css",
+    ]
+  }
+}
diff --git a/core/fxge/BUILD.gn b/core/fxge/BUILD.gn
index 6168fa9..03bfd4b 100644
--- a/core/fxge/BUILD.gn
+++ b/core/fxge/BUILD.gn
@@ -5,6 +5,7 @@
 import("//build/config/freetype/freetype.gni")
 import("//build/config/jumbo.gni")
 import("../../pdfium.gni")
+import("../../testing/test.gni")
 
 config("fxge_warnings") {
   visibility = [ ":*" ]
@@ -175,3 +176,16 @@
 
   visibility = [ "../../*" ]
 }
+
+pdfium_unittest_source_set("unittests") {
+  sources = [
+    "dib/cfx_dibitmap_unittest.cpp",
+    "dib/cstretchengine_unittest.cpp",
+  ]
+  deps = [
+    ":fxge",
+    "../fpdfapi/parser",
+    "../fpdfapi/render",
+  ]
+  pdfium_root_dir = "../../"
+}
diff --git a/fpdfsdk/BUILD.gn b/fpdfsdk/BUILD.gn
index bf80636..3799d35 100644
--- a/fpdfsdk/BUILD.gn
+++ b/fpdfsdk/BUILD.gn
@@ -4,6 +4,7 @@
 
 import("//build/config/jumbo.gni")
 import("../pdfium.gni")
+import("../testing/test.gni")
 
 jumbo_source_set("fpdfsdk") {
   sources = [
@@ -88,3 +89,19 @@
     allow_circular_includes_from += [ "fpdfxfa" ]
   }
 }
+
+pdfium_unittest_source_set("unittests") {
+  sources = [
+    "fpdf_catalog_unittest.cpp",
+    "fpdf_doc_unittest.cpp",
+    "fpdf_editimg_unittest.cpp",
+  ]
+  deps = [
+    ":fpdfsdk",
+    "../:pdfium_public_headers",
+    "../core/fpdfapi",
+    "../core/fpdfapi/parser",
+    "../core/fpdfdoc",
+  ]
+  pdfium_root_dir = "../"
+}
diff --git a/fxbarcode/BUILD.gn b/fxbarcode/BUILD.gn
index b5aecb8..caf0784 100644
--- a/fxbarcode/BUILD.gn
+++ b/fxbarcode/BUILD.gn
@@ -4,6 +4,7 @@
 
 import("//build/config/jumbo.gni")
 import("../pdfium.gni")
+import("../testing/test.gni")
 
 assert(pdf_enable_xfa)
 
@@ -142,3 +143,19 @@
   configs += [ "../:pdfium_core_config" ]
   visibility = [ "../*" ]
 }
+
+pdfium_unittest_source_set("unittests") {
+  sources = [
+    "oned/BC_OnedCodaBarWriter_unittest.cpp",
+    "oned/BC_OnedCode128Writer_unittest.cpp",
+    "oned/BC_OnedCode39Writer_unittest.cpp",
+    "oned/BC_OnedEAN13Writer_unittest.cpp",
+    "oned/BC_OnedEAN8Writer_unittest.cpp",
+    "oned/BC_OnedUPCAWriter_unittest.cpp",
+    "pdf417/BC_PDF417HighLevelEncoder_unittest.cpp",
+  ]
+  deps = [
+    ":fxbarcode",
+  ]
+  pdfium_root_dir = "../"
+}
diff --git a/fxjs/BUILD.gn b/fxjs/BUILD.gn
index 673386b..09595e3 100644
--- a/fxjs/BUILD.gn
+++ b/fxjs/BUILD.gn
@@ -4,6 +4,7 @@
 
 import("//build/config/jumbo.gni")
 import("../pdfium.gni")
+import("../testing/test.gni")
 
 jumbo_source_set("fxjs") {
   sources = [
@@ -445,3 +446,20 @@
     }
   }
 }
+
+if (pdf_enable_v8) {
+  pdfium_unittest_source_set("unittests") {
+    sources = [
+      "cfx_v8_unittest.cpp",
+      "cfx_v8_unittest.h",
+      "cfxjs_engine_unittest.cpp",
+      "cjs_publicmethods_unittest.cpp",
+      "cjs_util_unittest.cpp",
+    ]
+    configs = [ "//v8:external_startup_data" ]
+    deps = [
+      ":fxjs",
+    ]
+    pdfium_root_dir = "../"
+  }
+}
diff --git a/testing/BUILD.gn b/testing/BUILD.gn
index 0dd6a82..c231e22 100644
--- a/testing/BUILD.gn
+++ b/testing/BUILD.gn
@@ -10,6 +10,7 @@
   sources = [
     "fx_string_testhelpers.cpp",
     "fx_string_testhelpers.h",
+    "pseudo_retainable.h",
     "string_write_stream.cpp",
     "string_write_stream.h",
     "test_support.cpp",
diff --git a/testing/test.gni b/testing/test.gni
index b69a070..0bfac46 100644
--- a/testing/test.gni
+++ b/testing/test.gni
@@ -263,3 +263,24 @@
     configs = default_executable_configs
   }
 }
+
+template("pdfium_unittest_source_set") {
+  source_set(target_name) {
+    _pdfium_root_dir = rebase_path(invoker.pdfium_root_dir, ".")
+
+    testonly = true
+    sources = invoker.sources
+    configs += [ _pdfium_root_dir + ":pdfium_core_config" ]
+    if (defined(invoker.configs)) {
+      configs += invoker.configs
+    }
+    deps = [
+      _pdfium_root_dir + ":pdfium_unittest_deps",
+    ]
+    if (defined(invoker.deps)) {
+      deps += invoker.deps
+    }
+    visibility = [ _pdfium_root_dir + ":*" ]
+    forward_variables_from(invoker, [ "cflags" ])
+  }
+}
diff --git a/xfa/fde/BUILD.gn b/xfa/fde/BUILD.gn
index 3c600ec..ff728a7 100644
--- a/xfa/fde/BUILD.gn
+++ b/xfa/fde/BUILD.gn
@@ -4,6 +4,7 @@
 
 import("//build/config/jumbo.gni")
 import("../../pdfium.gni")
+import("../../testing/test.gni")
 
 assert(pdf_enable_xfa)
 
@@ -27,3 +28,14 @@
   ]
   visibility = [ "../../*" ]
 }
+
+pdfium_unittest_source_set("unittests") {
+  sources = [
+    "cfde_texteditengine_unittest.cpp",
+  ]
+  deps = [
+    ":fde",
+    "../fgas",
+  ]
+  pdfium_root_dir = "../../"
+}
diff --git a/xfa/fgas/BUILD.gn b/xfa/fgas/BUILD.gn
index c34aa09..d2819b8 100644
--- a/xfa/fgas/BUILD.gn
+++ b/xfa/fgas/BUILD.gn
@@ -4,6 +4,7 @@
 
 import("//build/config/jumbo.gni")
 import("../../pdfium.gni")
+import("../../testing/test.gni")
 
 assert(pdf_enable_xfa)
 
@@ -55,3 +56,18 @@
     ]
   }
 }
+
+pdfium_unittest_source_set("unittests") {
+  sources = [
+    "crt/cfgas_formatstring_unittest.cpp",
+    "layout/cfx_rtfbreak_unittest.cpp",
+    "layout/cfx_txtbreak_unittest.cpp",
+  ]
+  deps = [
+    ":fgas",
+    "../../core/fpdfapi",
+    "../../core/fxge",
+    "../fxfa/parser",
+  ]
+  pdfium_root_dir = "../../"
+}
diff --git a/xfa/fwl/BUILD.gn b/xfa/fwl/BUILD.gn
index bcccf8d..f6ca141 100644
--- a/xfa/fwl/BUILD.gn
+++ b/xfa/fwl/BUILD.gn
@@ -4,6 +4,7 @@
 
 import("//build/config/jumbo.gni")
 import("../../pdfium.gni")
+import("../../testing/test.gni")
 
 assert(pdf_enable_xfa)
 
@@ -135,3 +136,14 @@
   ]
   visibility = [ "../../*" ]
 }
+
+pdfium_unittest_source_set("unittests") {
+  sources = [
+    "cfx_barcode_unittest.cpp",
+  ]
+  deps = [
+    ":fwl",
+    "../../core/fxge",
+  ]
+  pdfium_root_dir = "../../"
+}
diff --git a/xfa/fxfa/BUILD.gn b/xfa/fxfa/BUILD.gn
index d6417b7..0c44f6b 100644
--- a/xfa/fxfa/BUILD.gn
+++ b/xfa/fxfa/BUILD.gn
@@ -4,6 +4,7 @@
 
 import("//build/config/jumbo.gni")
 import("../../pdfium.gni")
+import("../../testing/test.gni")
 
 assert(pdf_enable_xfa)
 
@@ -128,3 +129,14 @@
   ]
   visibility = [ "../../*" ]
 }
+
+pdfium_unittest_source_set("unittests") {
+  sources = [
+    "cxfa_ffbarcode_unittest.cpp",
+    "cxfa_textparser_unittest.cpp",
+  ]
+  deps = [
+    ":fxfa",
+  ]
+  pdfium_root_dir = "../../"
+}
diff --git a/xfa/fxfa/fm2js/BUILD.gn b/xfa/fxfa/fm2js/BUILD.gn
index 8da1ec5..930c452 100644
--- a/xfa/fxfa/fm2js/BUILD.gn
+++ b/xfa/fxfa/fm2js/BUILD.gn
@@ -4,6 +4,7 @@
 
 import("//build/config/jumbo.gni")
 import("../../../pdfium.gni")
+import("../../../testing/test.gni")
 
 assert(pdf_enable_xfa)
 
@@ -30,3 +31,16 @@
   ]
   visibility = [ "../../../*" ]
 }
+
+pdfium_unittest_source_set("unittests") {
+  sources = [
+    "cxfa_fmexpression_unittest.cpp",
+    "cxfa_fmlexer_unittest.cpp",
+    "cxfa_fmparser_unittest.cpp",
+    "cxfa_fmsimpleexpression_unittest.cpp",
+  ]
+  deps = [
+    ":fm2js",
+  ]
+  pdfium_root_dir = "../../../"
+}
diff --git a/xfa/fxfa/parser/BUILD.gn b/xfa/fxfa/parser/BUILD.gn
index bd7446d..8575a01 100644
--- a/xfa/fxfa/parser/BUILD.gn
+++ b/xfa/fxfa/parser/BUILD.gn
@@ -4,6 +4,7 @@
 
 import("//build/config/jumbo.gni")
 import("../../../pdfium.gni")
+import("../../../testing/test.gni")
 
 assert(pdf_enable_xfa)
 
@@ -719,3 +720,18 @@
   ]
   visibility = [ "../../../*" ]
 }
+
+pdfium_unittest_source_set("unittests") {
+  sources = [
+    "cxfa_document_parser_unittest.cpp",
+    "cxfa_localevalue_unittest.cpp",
+    "cxfa_node_unittest.cpp",
+    "cxfa_nodeiteratortemplate_unittest.cpp",
+    "cxfa_xmllocale_unittest.cpp",
+    "xfa_utils_unittest.cpp",
+  ]
+  deps = [
+    ":parser",
+  ]
+  pdfium_root_dir = "../../../"
+}