/* * Copyright 2013-present Facebook, Inc. * * 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.facebook.buck.android; import static com.facebook.buck.jvm.java.JavaCompilationConstants.ANDROID_JAVAC_OPTIONS; import static com.facebook.buck.jvm.java.JavaCompilationConstants.DEFAULT_JAVAC; import static com.facebook.buck.jvm.java.JavaCompilationConstants.DEFAULT_JAVAC_OPTIONS; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import com.facebook.buck.cli.FakeBuckConfig; import com.facebook.buck.jvm.java.AnnotationProcessingParams; import com.facebook.buck.jvm.java.FakeJavaLibrary; import com.facebook.buck.jvm.java.JavaBuckConfig; import com.facebook.buck.jvm.java.JavacFactory; import com.facebook.buck.jvm.java.JavacOptions; import com.facebook.buck.jvm.java.JavacToJarStepFactory; import com.facebook.buck.model.BuildTarget; import com.facebook.buck.model.BuildTargetFactory; import com.facebook.buck.rules.BuildRule; import com.facebook.buck.rules.BuildRuleParams; import com.facebook.buck.rules.BuildRuleResolver; import com.facebook.buck.rules.DefaultTargetNodeToBuildRuleTransformer; import com.facebook.buck.rules.FakeBuildRule; import com.facebook.buck.rules.FakeBuildRuleParamsBuilder; import com.facebook.buck.rules.FakeSourcePath; import com.facebook.buck.rules.SourcePathResolver; import com.facebook.buck.rules.SourcePathRuleFinder; import com.facebook.buck.rules.TargetGraph; import com.facebook.buck.util.DependencyMode; import com.facebook.buck.util.MoreCollectors; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSortedSet; import java.util.Optional; import org.hamcrest.Matchers; import org.junit.Test; public class AndroidLibraryGraphEnhancerTest { @Test public void testEmptyResources() { BuildTarget buildTarget = BuildTargetFactory.newInstance("//java/com/example:library"); AndroidLibraryGraphEnhancer graphEnhancer = new AndroidLibraryGraphEnhancer( buildTarget, new FakeBuildRuleParamsBuilder(buildTarget).build(), DEFAULT_JAVAC, DEFAULT_JAVAC_OPTIONS, DependencyMode.FIRST_ORDER, /* forceFinalResourceIds */ false, /* unionPackage */ Optional.empty(), /* rName */ Optional.empty(), false); Optional<DummyRDotJava> result = graphEnhancer.getBuildableForAndroidResources( new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer()), /* createdBuildableIfEmptyDeps */ false); assertFalse(result.isPresent()); } @Test public void testBuildRuleResolverCaching() { BuildTarget buildTarget = BuildTargetFactory.newInstance("//java/com/example:library"); AndroidLibraryGraphEnhancer graphEnhancer = new AndroidLibraryGraphEnhancer( buildTarget, new FakeBuildRuleParamsBuilder(buildTarget).build(), DEFAULT_JAVAC, DEFAULT_JAVAC_OPTIONS, DependencyMode.FIRST_ORDER, /* forceFinalResourceIds */ false, /* unionPackage */ Optional.empty(), /* rName */ Optional.empty(), false); BuildRuleResolver buildRuleResolver = new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer()); Optional<DummyRDotJava> result = graphEnhancer.getBuildableForAndroidResources( buildRuleResolver, /* createdBuildableIfEmptyDeps */ true); Optional<DummyRDotJava> secondResult = graphEnhancer.getBuildableForAndroidResources( buildRuleResolver, /* createdBuildableIfEmptyDeps */ true); assertThat(result.get(), Matchers.sameInstance(secondResult.get())); } @Test public void testBuildableIsCreated() { BuildTarget buildTarget = BuildTargetFactory.newInstance("//java/com/example:library"); BuildRuleResolver ruleResolver = new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer()); SourcePathRuleFinder ruleFinder = new SourcePathRuleFinder(ruleResolver); BuildRule resourceRule1 = ruleResolver.addToIndex( AndroidResourceRuleBuilder.newBuilder() .setRuleFinder(ruleFinder) .setBuildTarget(BuildTargetFactory.newInstance("//android_res/com/example:res1")) .setRDotJavaPackage("com.facebook") .setRes(new FakeSourcePath("android_res/com/example/res1")) .build()); BuildRule resourceRule2 = ruleResolver.addToIndex( AndroidResourceRuleBuilder.newBuilder() .setRuleFinder(ruleFinder) .setBuildTarget(BuildTargetFactory.newInstance("//android_res/com/example:res2")) .setRDotJavaPackage("com.facebook") .setRes(new FakeSourcePath("android_res/com/example/res2")) .build()); BuildRuleParams buildRuleParams = new FakeBuildRuleParamsBuilder(buildTarget) .setDeclaredDeps(ImmutableSortedSet.of(resourceRule1, resourceRule2)) .build(); AndroidLibraryGraphEnhancer graphEnhancer = new AndroidLibraryGraphEnhancer( buildTarget, buildRuleParams, DEFAULT_JAVAC, DEFAULT_JAVAC_OPTIONS, DependencyMode.FIRST_ORDER, /* forceFinalResourceIds */ false, /* unionPackage */ Optional.empty(), /* rName */ Optional.empty(), false); Optional<DummyRDotJava> dummyRDotJava = graphEnhancer.getBuildableForAndroidResources( ruleResolver, /* createBuildableIfEmptyDeps */ false); assertTrue(dummyRDotJava.isPresent()); assertEquals( "DummyRDotJava must contain these exact AndroidResourceRules.", // Note: these are the reverse order to which they are in the buildRuleParams. ImmutableList.of(resourceRule1, resourceRule2), dummyRDotJava.get().getAndroidResourceDeps()); assertEquals( "//java/com/example:library#dummy_r_dot_java", dummyRDotJava.get().getFullyQualifiedName()); assertEquals( "DummyRDotJava must depend on the two AndroidResourceRules.", ImmutableSet.of("//android_res/com/example:res1", "//android_res/com/example:res2"), dummyRDotJava .get() .getBuildDeps() .stream() .map(Object::toString) .collect(MoreCollectors.toImmutableSet())); } @Test public void testCreatedBuildableHasOverriddenJavacConfig() { BuildTarget buildTarget = BuildTargetFactory.newInstance("//java/com/example:library"); BuildRuleResolver ruleResolver = new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer()); SourcePathRuleFinder ruleFinder = new SourcePathRuleFinder(ruleResolver); BuildRule resourceRule1 = ruleResolver.addToIndex( AndroidResourceRuleBuilder.newBuilder() .setRuleFinder(ruleFinder) .setBuildTarget(BuildTargetFactory.newInstance("//android_res/com/example:res1")) .setRDotJavaPackage("com.facebook") .setRes(new FakeSourcePath("android_res/com/example/res1")) .build()); BuildRule resourceRule2 = ruleResolver.addToIndex( AndroidResourceRuleBuilder.newBuilder() .setRuleFinder(ruleFinder) .setBuildTarget(BuildTargetFactory.newInstance("//android_res/com/example:res2")) .setRDotJavaPackage("com.facebook") .setRes(new FakeSourcePath("android_res/com/example/res2")) .build()); BuildRuleParams buildRuleParams = new FakeBuildRuleParamsBuilder(buildTarget) .setDeclaredDeps(ImmutableSortedSet.of(resourceRule1, resourceRule2)) .build(); AndroidLibraryGraphEnhancer graphEnhancer = new AndroidLibraryGraphEnhancer( buildTarget, buildRuleParams, DEFAULT_JAVAC, JavacOptions.builder(ANDROID_JAVAC_OPTIONS) .setAnnotationProcessingParams( AnnotationProcessingParams.builder().setProcessOnly(true).build()) .setSourceLevel("7") .setTargetLevel("7") .build(), DependencyMode.FIRST_ORDER, /* forceFinalResourceIds */ false, /* unionPackage */ Optional.empty(), /* rName */ Optional.empty(), false); Optional<DummyRDotJava> dummyRDotJava = graphEnhancer.getBuildableForAndroidResources( ruleResolver, /* createBuildableIfEmptyDeps */ false); assertTrue(dummyRDotJava.isPresent()); JavacOptions javacOptions = ((JavacToJarStepFactory) dummyRDotJava.get().getCompileStepFactory()).getJavacOptions(); assertFalse(javacOptions.getAnnotationProcessingParams().getProcessOnly()); assertEquals("7", javacOptions.getSourceLevel()); } @Test public void testDummyRDotJavaRuleInheritsJavacOptionsDepsAndNoOthers() { BuildRuleResolver resolver = new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer()); SourcePathRuleFinder ruleFinder = new SourcePathRuleFinder(resolver); SourcePathResolver pathResolver = new SourcePathResolver(ruleFinder); FakeBuildRule javacDep = new FakeJavaLibrary(BuildTargetFactory.newInstance("//:javac_dep"), pathResolver); resolver.addToIndex(javacDep); FakeBuildRule dep = new FakeJavaLibrary(BuildTargetFactory.newInstance("//:dep"), pathResolver); resolver.addToIndex(dep); JavaBuckConfig javaConfig = FakeBuckConfig.builder() .setSections(ImmutableMap.of("tools", ImmutableMap.of("javac_jar", "//:javac_dep"))) .build() .getView(JavaBuckConfig.class); BuildTarget target = BuildTargetFactory.newInstance("//:rule"); JavacOptions options = JavacOptions.builder().setSourceLevel("5").setTargetLevel("5").build(); AndroidLibraryGraphEnhancer graphEnhancer = new AndroidLibraryGraphEnhancer( target, new FakeBuildRuleParamsBuilder(target) .setDeclaredDeps(ImmutableSortedSet.of(dep)) .build(), JavacFactory.create(ruleFinder, javaConfig, null), options, DependencyMode.FIRST_ORDER, /* forceFinalResourceIds */ false, /* unionPackage */ Optional.empty(), /* rName */ Optional.empty(), false); Optional<DummyRDotJava> result = graphEnhancer.getBuildableForAndroidResources( resolver, /* createdBuildableIfEmptyDeps */ true); assertTrue(result.isPresent()); assertThat(result.get().getBuildDeps(), Matchers.<BuildRule>contains(javacDep)); } }