experimental_ios_test: Support non-xctests

--
MOS_MIGRATED_REVID=96245678
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/TestSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/TestSupport.java
index 89c93d7..ebc6820 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/TestSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/TestSupport.java
@@ -31,6 +31,8 @@
 import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
 import com.google.devtools.build.lib.util.FileType;
 
+import java.util.List;
+
 /**
  * Support for running XcTests.
  */
@@ -57,23 +59,30 @@
   }
 
   private void registerTestScriptSubstitutionAction() {
-    // testIpa is the app actually containing the XcTests
+    // testIpa is the app actually containing the tests
     Artifact testIpa = testIpa();
-    // xctestIpa is the app bundle being tested
-    Artifact xctestIpa = xctestIpa();
 
     ImmutableList.Builder<Substitution> substitutions = new ImmutableList.Builder<Substitution>()
         .add(Substitution.of("%(test_app_ipa)s", testIpa.getRootRelativePathString()))
         .add(Substitution.of("%(test_app_name)s", baseNameWithoutIpa(testIpa)))
 
-        .add(Substitution.of("%(xctest_app_ipa)s", xctestIpa.getRootRelativePathString()))
-        .add(Substitution.of("%(xctest_app_name)s", baseNameWithoutIpa(xctestIpa)))
-
         .add(Substitution.of("%(iossim_path)s", iossim().getRootRelativePath().getPathString()))
         .add(Substitution.of("%(plugin_jars)s", Artifact.joinRootRelativePaths(":", plugins())))
 
         .addAll(deviceSubstitutions().getSubstitutionsForTestRunnerScript());
 
+    // xctestIpa is the app bundle being tested
+    Optional<Artifact> xctestIpa = xctestIpa();
+    if (xctestIpa.isPresent()) {
+      substitutions
+          .add(Substitution.of("%(xctest_app_ipa)s", xctestIpa.get().getRootRelativePathString()))
+          .add(Substitution.of("%(xctest_app_name)s", baseNameWithoutIpa(xctestIpa.get())));
+    } else {
+      substitutions
+          .add(Substitution.of("%(xctest_app_ipa)s", ""))
+          .add(Substitution.of("%(xctest_app_name)s", ""));
+    }
+    
     Optional<Artifact> testRunner = testRunner();
     if (testRunner.isPresent()) {
       substitutions.add(
@@ -95,11 +104,21 @@
     return ruleContext.getImplicitOutputArtifact(ReleaseBundlingSupport.IPA);
   }
 
-  private Artifact xctestIpa() {
+  private Optional<Artifact> xctestIpa() {
     FileProvider fileProvider =
         ruleContext.getPrerequisite("xctest_app", Mode.TARGET, FileProvider.class);
-    return Iterables.getOnlyElement(
-        Artifact.filterFiles(fileProvider.getFilesToBuild(), FileType.of(".ipa")));
+    if (fileProvider == null) {
+      return Optional.absent();
+    }
+    List<Artifact> files =
+        Artifact.filterFiles(fileProvider.getFilesToBuild(), FileType.of(".ipa"));
+    if (files.size() == 0) {
+      return Optional.absent();
+    } else if (files.size() == 1) {
+      return Optional.of(Iterables.getOnlyElement(files));
+    } else {
+      throw new IllegalStateException("Expected 0 or 1 files in xctest_app, got: " + files);
+    }
   }
 
   private Artifact iossim() {
@@ -119,7 +138,7 @@
   TestSupport addRunfiles(Runfiles.Builder runfilesBuilder) {
     runfilesBuilder
         .addArtifact(testIpa())
-        .addArtifact(xctestIpa())
+        .addArtifacts(xctestIpa().asSet())
         .addArtifact(generatedTestScript())
         .addArtifact(iossim())
         .addTransitiveArtifacts(deviceRunfiles())
@@ -147,7 +166,7 @@
    * Adds files which must be built in order to run this test to builder.
    */
   TestSupport addFilesToBuild(NestedSetBuilder<Artifact> builder) {
-    builder.add(testIpa()).add(xctestIpa());
+    builder.add(testIpa()).addAll(xctestIpa().asSet());
     return this;
   }