[iOS] Add xcode_test_application_name property to create_bundle target.

This CL adds xcode_test_application_name to create_bundle target so 
that the relationship between xcode unit or ui test target and test 
application target can be specified in BUILD files instead of being 
identified by parsing target names in GN.

Bug: 741147, 709289
Change-Id: Idf0cb700b300d80d49803dae33eb90c87c0e41a0
Reviewed-on: https://chromium-review.googlesource.com/566587
Commit-Queue: Yuke Liao <liaoyuke@chromium.org>
Reviewed-by: Dirk Pranke <dpranke@chromium.org>
Reviewed-by: Sylvain Defresne <sdefresne@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#486482}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 148fef685ebaea6f26c2b60b7006e9b7f711d228
diff --git a/tools/gn/bundle_data.h b/tools/gn/bundle_data.h
index 4ea1499..26c972c 100644
--- a/tools/gn/bundle_data.h
+++ b/tools/gn/bundle_data.h
@@ -107,6 +107,13 @@
   std::string& product_type() { return product_type_; }
   const std::string& product_type() const { return product_type_; }
 
+  std::string& xcode_test_application_name() {
+    return xcode_test_application_name_;
+  }
+  const std::string& xcode_test_application_name() const {
+    return xcode_test_application_name_;
+  }
+
   void set_code_signing_script(const SourceFile& script_file) {
     code_signing_script_ = script_file;
   }
@@ -161,6 +168,11 @@
   // the Xcode project file when using --ide=xcode.
   std::string product_type_;
 
+  // Each Xcode unit test or ui test target must have a test application target,
+  // and this value corresponds to the target name. This is only used to
+  // generate the Xcode project when using --ide=xcode.
+  std::string xcode_test_application_name_;
+
   // Holds the values (script name, sources, outputs, script arguments) for the
   // code signing step if defined.
   SourceFile code_signing_script_;
diff --git a/tools/gn/create_bundle_target_generator.cc b/tools/gn/create_bundle_target_generator.cc
index fca4f2a..22c6cd6 100644
--- a/tools/gn/create_bundle_target_generator.cc
+++ b/tools/gn/create_bundle_target_generator.cc
@@ -49,6 +49,9 @@
   if (!FillProductType())
     return;
 
+  if (!FillXcodeTestApplicationName())
+    return;
+
   if (!FillCodeSigningScript())
     return;
 
@@ -134,6 +137,20 @@
   return true;
 }
 
+bool CreateBundleTargetGenerator::FillXcodeTestApplicationName() {
+  const Value* value =
+      scope_->GetValue(variables::kXcodeTestApplicationName, true);
+  if (!value)
+    return true;
+
+  if (!value->VerifyTypeIs(Value::STRING, err_))
+    return false;
+
+  target_->bundle_data().xcode_test_application_name().assign(
+      value->string_value());
+  return true;
+}
+
 bool CreateBundleTargetGenerator::FillCodeSigningScript() {
   const Value* value = scope_->GetValue(variables::kCodeSigningScript, true);
   if (!value)
diff --git a/tools/gn/create_bundle_target_generator.h b/tools/gn/create_bundle_target_generator.h
index 4fdfcd2..bf2ad2f 100644
--- a/tools/gn/create_bundle_target_generator.h
+++ b/tools/gn/create_bundle_target_generator.h
@@ -30,6 +30,7 @@
   bool FillXcodeExtraAttributes();
 
   bool FillProductType();
+  bool FillXcodeTestApplicationName();
 
   bool FillCodeSigningScript();
   bool FillCodeSigningSources();
diff --git a/tools/gn/docs/reference.md b/tools/gn/docs/reference.md
index f381f74..da9cd1c 100644
--- a/tools/gn/docs/reference.md
+++ b/tools/gn/docs/reference.md
@@ -124,6 +124,7 @@
     *   [response_file_contents: [string list] Contents of .rsp file for actions.](#response_file_contents)
     *   [script: [file name] Script file for actions.](#script)
     *   [sources: [file list] Source files for a target.](#sources)
+    *   [xcode_test_application_name: [string] Xcode test application name for unit or ui test.](#xcode_test_application_name)
     *   [testonly: [boolean] Declares a target must only be used for testing.](#testonly)
     *   [visibility: [label list] A list of labels that can depend on a target.](#visibility)
     *   [write_runtime_deps: Writes the target's runtime_deps to the given path.](#write_runtime_deps)
@@ -5206,6 +5207,24 @@
   copy
     The source are the source files to copy.
 ```
+### <a name="xcode_test_application_name"></a>**xcode_test_application_name**: Xcode test application name for unit or ui test target.
+
+```
+  Each Xcode unit and ui test target must have a test application target, and
+  this value is used to specify the relationship. Only meaningful to Xcode
+  (used as part of the Xcode project generation).
+
+  See "gn help create_bundle" for more information.
+```
+
+#### **Example**
+
+```
+  create_bundle("chrome_xctest") {
+    xcode_test_application_name = "chrome"
+    ...
+  }
+```
 ### <a name="testonly"></a>**testonly**: Declares a target must only be used for testing.
 
 ```
diff --git a/tools/gn/functions_target.cc b/tools/gn/functions_target.cc
index cd58ff1..f4369d6 100644
--- a/tools/gn/functions_target.cc
+++ b/tools/gn/functions_target.cc
@@ -361,7 +361,8 @@
   bundle_root_dir*, bundle_resources_dir*, bundle_executable_dir*,
   bundle_plugins_dir*, bundle_deps_filter, deps, data_deps, public_deps,
   visibility, product_type, code_signing_args, code_signing_script,
-  code_signing_sources, code_signing_outputs, extra_attributes
+  code_signing_sources, code_signing_outputs, xcode_extra_attributes,
+  xcode_test_application_name
   * = required
 
 Example
diff --git a/tools/gn/variables.cc b/tools/gn/variables.cc
index eb69a18..5b80181 100644
--- a/tools/gn/variables.cc
+++ b/tools/gn/variables.cc
@@ -1746,6 +1746,27 @@
     The source are the source files to copy.
 )";
 
+const char kXcodeTestApplicationName[] = "xcode_test_application_name";
+const char kXcodeTestApplicationName_HelpShort[] =
+    "test_application_name: [string] Test application name for unit or ui test "
+    "target.";
+const char kXcodeTestApplicationName_Help[] =
+    R"(test_application_name: Test application name for unit or ui test target.
+
+  Each unit and ui test target must have a test application target, and this
+  value is used to specify the relationship. Only meaningful to Xcode (used as
+  part of the Xcode project generation).
+
+  See "gn help create_bundle" for more information.
+
+Exmaple
+
+  create_bundle("chrome_xctest") {
+    test_application_name = "chrome"
+    ...
+  }
+)";
+
 const char kTestonly[] = "testonly";
 const char kTestonly_HelpShort[] =
     "testonly: [boolean] Declares a target must only be used for testing.";
@@ -1939,6 +1960,7 @@
     INSERT_VARIABLE(ResponseFileContents)
     INSERT_VARIABLE(Script)
     INSERT_VARIABLE(Sources)
+    INSERT_VARIABLE(XcodeTestApplicationName)
     INSERT_VARIABLE(Testonly)
     INSERT_VARIABLE(Visibility)
     INSERT_VARIABLE(WriteRuntimeDeps)
diff --git a/tools/gn/variables.h b/tools/gn/variables.h
index 2d2e0c7..0ea00d5 100644
--- a/tools/gn/variables.h
+++ b/tools/gn/variables.h
@@ -279,6 +279,10 @@
 extern const char kSources_HelpShort[];
 extern const char kSources_Help[];
 
+extern const char kXcodeTestApplicationName[];
+extern const char kXcodeTestApplicationName_HelpShort[];
+extern const char kXcodeTestApplicationName_Help[];
+
 extern const char kTestonly[];
 extern const char kTestonly_HelpShort[];
 extern const char kTestonly_Help[];
diff --git a/tools/gn/xcode_writer.cc b/tools/gn/xcode_writer.cc
index 3128e6c..fbcc069 100644
--- a/tools/gn/xcode_writer.cc
+++ b/tools/gn/xcode_writer.cc
@@ -131,6 +131,8 @@
                         base::CompareCase::SENSITIVE);
 }
 
+// TODO(crbug.com/741147) Remove this function and switch to use
+// test_application_name once the bug is fixed and GN has rolled past it.
 const Target* FindXCTestApplicationTarget(
     const Target* xctest_module_target,
     const std::vector<const Target*>& targets) {
@@ -151,6 +153,8 @@
   return nullptr;
 }
 
+// TODO(crbug.com/741147) Remove this function and switch to use
+// test_application_name once the bug is fixed and GN has rolled past it.
 // Given XCTest module targets, find the corresponding application targets and
 // the mappings between them.
 void FindXCTestApplicationTargets(