blob: 050daa82010dce03c144cfc21e061afca053a32c [file] [log] [blame]
// Copyright 2017 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.lib.bazel.rules.android;
import static com.google.devtools.build.lib.packages.Attribute.attr;
import static com.google.devtools.build.lib.packages.BuildType.LABEL;
import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;
import static com.google.devtools.build.lib.packages.BuildType.TRISTATE;
import static com.google.devtools.build.lib.packages.ImplicitOutputsFunction.fromFunctions;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.analysis.BaseRuleClasses;
import com.google.devtools.build.lib.analysis.RuleDefinition;
import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
import com.google.devtools.build.lib.bazel.rules.java.BazelJavaRuleClasses.BaseJavaBinaryRule;
import com.google.devtools.build.lib.packages.ImplicitOutputsFunction;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType;
import com.google.devtools.build.lib.packages.SkylarkProviderIdentifier;
import com.google.devtools.build.lib.packages.TriState;
import com.google.devtools.build.lib.rules.android.AndroidFeatureFlagSetProvider;
import com.google.devtools.build.lib.rules.android.AndroidLocalTestBaseRule;
import com.google.devtools.build.lib.rules.config.ConfigFeatureFlagTransitionFactory;
import com.google.devtools.build.lib.rules.cpp.CppRuleClasses;
import com.google.devtools.build.lib.rules.java.JavaConfiguration;
import com.google.devtools.build.lib.rules.java.JavaInfo;
import com.google.devtools.build.lib.rules.java.JavaSemantics;
/** Rule definition for Bazel android_local_test */
public class BazelAndroidLocalTestRule implements RuleDefinition {
protected static final String JUNIT_TESTRUNNER = "//tools/jdk:TestRunner_deploy.jar";
private static final ImmutableCollection<String> ALLOWED_RULES_IN_DEPS =
ImmutableSet.of(
"aar_import",
"android_library",
"java_import",
"java_library",
"java_lite_proto_library");
static final ImplicitOutputsFunction ANDROID_ROBOLECTRIC_IMPLICIT_OUTPUTS = fromFunctions(
JavaSemantics.JAVA_BINARY_CLASS_JAR,
JavaSemantics.JAVA_BINARY_SOURCE_JAR,
JavaSemantics.JAVA_BINARY_DEPLOY_JAR);
@Override
public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment environment) {
return builder
.requiresConfigurationFragments(JavaConfiguration.class)
.setImplicitOutputsFunction(ANDROID_ROBOLECTRIC_IMPLICIT_OUTPUTS)
.override(
attr("deps", LABEL_LIST)
.allowedFileTypes()
.allowedRuleClasses(ALLOWED_RULES_IN_DEPS)
.mandatoryProvidersList(
ImmutableList.of(
ImmutableList.of(
SkylarkProviderIdentifier.forKey(JavaInfo.PROVIDER.getKey())))))
.override(attr("$testsupport", LABEL).value(environment.getToolsLabel(JUNIT_TESTRUNNER)))
.add(
attr("$robolectric_implicit_classpath", LABEL_LIST)
.value(ImmutableList.of(environment.getToolsLabel("//tools/android:android_jar"))))
.override(attr("stamp", TRISTATE).value(TriState.NO))
.removeAttribute("classpath_resources")
.removeAttribute("create_executable")
.removeAttribute("deploy_manifest_lines")
.removeAttribute("distribs")
.removeAttribute("launcher")
.removeAttribute("main_class")
.removeAttribute("resources")
.removeAttribute("use_testrunner")
.removeAttribute(":java_launcher")
.cfg(
new ConfigFeatureFlagTransitionFactory(AndroidFeatureFlagSetProvider.FEATURE_FLAG_ATTR))
.addRequiredToolchains(CppRuleClasses.ccToolchainTypeAttribute(environment))
.build();
}
@Override
public Metadata getMetadata() {
return RuleDefinition.Metadata.builder()
.name("android_local_test")
.type(RuleClassType.TEST)
.ancestors(
AndroidLocalTestBaseRule.class,
BaseJavaBinaryRule.class,
BaseRuleClasses.TestBaseRule.class)
.factoryClass(BazelAndroidLocalTest.class)
.build();
}
}
/*<!-- #BLAZE_RULE (NAME = android_local_test, TYPE = TEST, FAMILY = Android) -->
<p>
This rule is for unit testing <code>android_library</code> rules locally
(as opposed to on a device).
It works with the Android Robolectric testing framework.
See the <a href="http://robolectric.org/">Android Robolectric</a> site for details about
writing Robolectric tests.
</p>
${IMPLICIT_OUTPUTS}
<h4 id="android_local_test_examples">Examples</h4>
<p>
To use Robolectric with <code>android_local_test</code>, add
<a href="https://github.com/robolectric/robolectric-bazel/tree/master/bazel">Robolectric's
repository</a> to your <code>WORKSPACE</code> file:
<pre class="code">
http_archive(
name = "robolectric",
urls = ["https://github.com/robolectric/robolectric/archive/&lt;COMMIT&gt;.tar.gz"],
strip_prefix = "robolectric-&lt;COMMIT&gt;",
sha256 = "&lt;HASH&gt;",
)
load("@robolectric//bazel:robolectric.bzl", "robolectric_repositories")
robolectric_repositories()
</pre>
This pulls in the <code>maven_jar</code> rules needed for Robolectric.
Then each <code>android_local_test</code> rule should depend on
<code>@robolectric//bazel:robolectric</code>. See example below.
</p>
<pre class="code">
android_local_test(
name = "SampleTest",
srcs = [
"SampleTest.java",
],
manifest = "LibManifest.xml",
deps = [
":sample_test_lib",
"@robolectric//bazel:robolectric",
],
)
android_library(
name = "sample_test_lib",
srcs = [
"Lib.java",
],
resource_files = glob(["res/**"]),
manifest = "AndroidManifest.xml",
)
</pre>
<!-- #END_BLAZE_RULE --> */
/* <!-- #BLAZE_RULE(android_local_test).IMPLICIT_OUTPUTS -->
<ul>
<li><code><var>name</var>.jar</code>: A Java archive of the test.</li>
<li><code><var>name</var>-src.jar</code>: An archive containing the sources
("source jar").</li>
<li><code><var>name</var>_deploy.jar</code>: A Java deploy archive suitable
for deployment (only built if explicitly requested).</li>
</ul>
<!-- #END_BLAZE_RULE.IMPLICIT_OUTPUTS --> */