| /* |
| * 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.java.JavaCompilationConstants.DEFAULT_JAVAC_OPTIONS; |
| import static com.facebook.buck.util.BuckConstant.BIN_DIR; |
| import static com.facebook.buck.util.BuckConstant.BIN_PATH; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertTrue; |
| |
| import com.facebook.buck.android.AndroidBinary.PackageType; |
| import com.facebook.buck.android.AndroidBinary.TargetCpuType; |
| import com.facebook.buck.model.BuildTarget; |
| import com.facebook.buck.model.BuildTargetFactory; |
| import com.facebook.buck.model.ImmutableFlavor; |
| import com.facebook.buck.rules.BuildRuleParams; |
| import com.facebook.buck.rules.BuildRuleResolver; |
| import com.facebook.buck.rules.FakeBuildRuleParamsBuilder; |
| import com.facebook.buck.rules.SourcePathResolver; |
| import com.facebook.buck.rules.TestSourcePath; |
| import com.facebook.buck.step.Step; |
| import com.facebook.buck.step.fs.MakeCleanDirectoryStep; |
| import com.facebook.buck.step.fs.MkdirAndSymlinkFileStep; |
| import com.facebook.buck.testutil.FakeProjectFilesystem; |
| import com.facebook.buck.testutil.MoreAsserts; |
| import com.google.common.base.Optional; |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.ImmutableSet; |
| |
| import org.easymock.EasyMock; |
| import org.junit.Test; |
| |
| import java.io.IOException; |
| import java.nio.file.Path; |
| import java.nio.file.Paths; |
| import java.util.List; |
| import java.util.Set; |
| |
| public class AaptPackageResourcesTest { |
| |
| /** |
| * Tests an android_binary with zero dependent android_library rules that contains an assets |
| * directory. |
| */ |
| @Test |
| public void testCreateAllAssetsDirectoryWithZeroAssetsDirectories() throws IOException { |
| ResourcesFilter resourcesFilter = EasyMock.createMock(ResourcesFilter.class); |
| EasyMock.replay(resourcesFilter); |
| |
| BuildRuleParams params = new FakeBuildRuleParamsBuilder( |
| BuildTarget.builder("//java/src/com/facebook/base", "apk") |
| .addFlavors(ImmutableFlavor.of("aapt_package")) |
| .build()) |
| .build(); |
| |
| // One android_binary rule that depends on the two android_library rules. |
| AaptPackageResources aaptPackageResources = new AaptPackageResources( |
| params, |
| new SourcePathResolver(new BuildRuleResolver()), |
| /* manifest */ new TestSourcePath("java/src/com/facebook/base/AndroidManifest.xml"), |
| resourcesFilter, |
| ImmutableList.<HasAndroidResourceDeps>of(), |
| ImmutableSet.<Path>of(), |
| PackageType.DEBUG, |
| /* cpuFilters */ ImmutableSet.<TargetCpuType>of(), |
| DEFAULT_JAVAC_OPTIONS, |
| /* rDotJavaNeedsDexing */ false, |
| /* shouldBuildStringSourceMap */ false, |
| /* shouldWarnIfMissingResources */ false, |
| /* skipCrunchPngs */ false); |
| |
| // Build up the parameters needed to invoke createAllAssetsDirectory(). |
| ImmutableList.Builder<Step> commands = ImmutableList.builder(); |
| |
| // Invoke createAllAssetsDirectory(), the method under test. |
| Optional<Path> allAssetsDirectory = aaptPackageResources.createAllAssetsDirectory( |
| /* assetsDirectories */ ImmutableSet.<Path>of(), |
| commands, |
| new FakeProjectFilesystem()); |
| EasyMock.verify(resourcesFilter); |
| |
| // Verify that no assets/ directory is used. |
| assertFalse("There should not be an assets/ directory to pass to aapt.", |
| allAssetsDirectory.isPresent()); |
| assertTrue("There should not be any commands to build up an assets/ directory.", |
| commands.build().isEmpty()); |
| } |
| |
| /** |
| * Tests an android_binary with one dependent android_library rule that contains an assets |
| * directory. |
| */ |
| @Test |
| public void testCreateAllAssetsDirectoryWithOneAssetsDirectory() throws IOException { |
| BuildRuleResolver ruleResolver = new BuildRuleResolver(); |
| |
| // Two android_library deps, one of which has an assets directory. |
| AndroidBinaryTest.createAndroidLibraryRule( |
| "//java/src/com/facebook/base:libraryOne", |
| ruleResolver, |
| null, /* resDirectory */ |
| null, /* assetDirectory */ |
| null /* nativeLibsDirectory */); |
| AndroidBinaryTest.createAndroidLibraryRule( |
| "//java/src/com/facebook/base:libraryTwo", |
| ruleResolver, |
| null, /* resDirectory */ |
| "java/src/com/facebook/base/assets2", |
| null /* nativeLibsDirectory */); |
| ResourcesFilter resourcesFilter = EasyMock.createMock(ResourcesFilter.class); |
| EasyMock.replay(resourcesFilter); |
| |
| AndroidResource resourceOne = (AndroidResource) ruleResolver.getRule( |
| BuildTargetFactory.newInstance("//java/src/com/facebook/base:libraryTwo_resources")); |
| |
| BuildRuleParams params = new FakeBuildRuleParamsBuilder( |
| BuildTarget.builder("//java/src/com/facebook/base", "apk") |
| .addFlavors(ImmutableFlavor.of("aapt_package")) |
| .build()) |
| .build(); |
| // One android_binary rule that depends on the two android_library rules. |
| AaptPackageResources aaptPackageResources = new AaptPackageResources( |
| params, |
| new SourcePathResolver(ruleResolver), |
| /* manifest */ new TestSourcePath("java/src/com/facebook/base/AndroidManifest.xml"), |
| resourcesFilter, |
| ImmutableList.<HasAndroidResourceDeps>of(), |
| ImmutableSet.<Path>of(), |
| PackageType.DEBUG, |
| /* cpuFilters */ ImmutableSet.<TargetCpuType>of(), |
| DEFAULT_JAVAC_OPTIONS, |
| /* rDotJavaNeedsDexing */ false, |
| /* shouldBuildStringSourceMap */ false, |
| /* shouldWarnIfMissingResources */ false, |
| /* skipCrunchPngs */ false); |
| |
| // Build up the parameters needed to invoke createAllAssetsDirectory(). |
| Set<Path> assetsDirectories = ImmutableSet.of(resourceOne.getAssets()); |
| ImmutableList.Builder<Step> commands = ImmutableList.builder(); |
| FakeProjectFilesystem filesystem = new FakeProjectFilesystem(); |
| filesystem.touch(Paths.get("java/src/com/facebook/base/assets2/fonts/Theinhardt-Medium.otf")); |
| filesystem.touch(Paths.get("java/src/com/facebook/base/assets2/fonts/Theinhardt-Regular.otf")); |
| |
| // Some special files should be ignored. |
| filesystem.touch(Paths.get("facebook/base/assets2/fonts/.svn")); |
| filesystem.touch(Paths.get("facebook/base/assets2/fonts/.git")); |
| filesystem.touch(Paths.get("facebook/base/assets2/fonts/.DS_Store")); |
| filesystem.touch(Paths.get("facebook/base/assets2/fonts/Something.scc")); |
| filesystem.touch(Paths.get("facebook/base/assets2/fonts/CVS")); |
| filesystem.touch(Paths.get("facebook/base/assets2/fonts/thumbs.db")); |
| filesystem.touch(Paths.get("facebook/base/assets2/fonts/picasa.ini")); |
| filesystem.touch(Paths.get("facebook/base/assets2/fonts/something~")); |
| |
| // Invoke createAllAssetsDirectory(), the method under test. |
| Optional<Path> allAssetsDirectory = aaptPackageResources.createAllAssetsDirectory( |
| assetsDirectories, commands, filesystem); |
| EasyMock.verify(resourcesFilter); |
| |
| // Verify that the existing assets/ directory will be passed to aapt. |
| assertTrue(allAssetsDirectory.isPresent()); |
| assertEquals( |
| "Even though there is only one assets directory, the one in " + |
| BIN_DIR + |
| " should be used.", |
| aaptPackageResources.getPathToAllAssetsDirectory(), |
| allAssetsDirectory.get()); |
| } |
| |
| /** |
| * Tests an android_binary with multiple dependent android_library rules, each with its own assets |
| * directory. |
| */ |
| @Test |
| public void testCreateAllAssetsDirectoryWithMultipleAssetsDirectories() throws IOException { |
| BuildRuleResolver ruleResolver = new BuildRuleResolver(); |
| |
| // Two android_library deps, each with an assets directory. |
| AndroidBinaryTest.createAndroidLibraryRule( |
| "//facebook/base:libraryOne", |
| ruleResolver, |
| null, /* resDirectory */ |
| "facebook/base/assets1", |
| null /* nativeLibsDirectory */); |
| AndroidBinaryTest.createAndroidLibraryRule( |
| "//facebook/base:libraryTwo", |
| ruleResolver, |
| null, /* resDirectory */ |
| "facebook/base/assets2", |
| null /* nativeLibsDirectory */); |
| ResourcesFilter resourcesFilter = EasyMock.createMock(ResourcesFilter.class); |
| EasyMock.replay(resourcesFilter); |
| |
| BuildRuleParams params = new FakeBuildRuleParamsBuilder( |
| BuildTarget |
| .builder("//facebook/base", "apk") |
| .addFlavors(ImmutableFlavor.of("aapt_package")) |
| .build()) |
| .build(); |
| // One android_binary rule that depends on the two android_library rules. |
| AaptPackageResources aaptPackageResources = new AaptPackageResources( |
| params, |
| new SourcePathResolver(ruleResolver), |
| /* manifest */ new TestSourcePath("facebook/base/AndroidManifest.xml"), |
| resourcesFilter, |
| ImmutableList.<HasAndroidResourceDeps>of(), |
| ImmutableSet.<Path>of(), |
| PackageType.DEBUG, |
| /* cpuFilters */ ImmutableSet.<TargetCpuType>of(), |
| DEFAULT_JAVAC_OPTIONS, |
| /* rDotJavaNeedsDexing */ false, |
| /* shouldBuildStringSourceMap */ false, |
| /* shouldWarnIfMissingResources */ false, |
| /* skipCrunchPngs */ false); |
| |
| AndroidResource resourceOne = (AndroidResource) ruleResolver.getRule( |
| BuildTargetFactory.newInstance("//facebook/base:libraryOne_resources")); |
| AndroidResource resourceTwo = (AndroidResource) ruleResolver.getRule( |
| BuildTargetFactory.newInstance("//facebook/base:libraryTwo_resources")); |
| |
| // Build up the parameters needed to invoke createAllAssetsDirectory(). |
| Set<Path> assetsDirectories = ImmutableSet.of( |
| resourceOne.getAssets(), |
| resourceTwo.getAssets()); |
| ImmutableList.Builder<Step> commands = ImmutableList.builder(); |
| |
| FakeProjectFilesystem filesystem = new FakeProjectFilesystem(); |
| filesystem.touch(Paths.get("facebook/base/assets1/guava-10.0.1-fork.dex.1.jar")); |
| filesystem.touch(Paths.get("facebook/base/assets2/fonts/Theinhardt-Medium.otf")); |
| filesystem.touch(Paths.get("facebook/base/assets2/fonts/Theinhardt-Regular.otf")); |
| |
| // Some special files should be ignored and shouldn't cause conflicts. |
| filesystem.touch(Paths.get("facebook/base/assets1/fonts/.svn")); |
| filesystem.touch(Paths.get("facebook/base/assets1/fonts/.git")); |
| filesystem.touch(Paths.get("facebook/base/assets1/fonts/.DS_Store")); |
| filesystem.touch(Paths.get("facebook/base/assets1/fonts/Something.scc")); |
| filesystem.touch(Paths.get("facebook/base/assets1/fonts/CVS")); |
| filesystem.touch(Paths.get("facebook/base/assets1/fonts/thumbs.db")); |
| filesystem.touch(Paths.get("facebook/base/assets1/fonts/picasa.ini")); |
| filesystem.touch(Paths.get("facebook/base/assets1/fonts/something~")); |
| |
| filesystem.touch(Paths.get("facebook/base/assets2/fonts/.svn")); |
| filesystem.touch(Paths.get("facebook/base/assets2/fonts/.git")); |
| filesystem.touch(Paths.get("facebook/base/assets2/fonts/.DS_Store")); |
| filesystem.touch(Paths.get("facebook/base/assets2/fonts/Something.scc")); |
| filesystem.touch(Paths.get("facebook/base/assets2/fonts/CVS")); |
| filesystem.touch(Paths.get("facebook/base/assets2/fonts/thumbs.db")); |
| filesystem.touch(Paths.get("facebook/base/assets2/fonts/picasa.ini")); |
| filesystem.touch(Paths.get("facebook/base/assets2/fonts/something~")); |
| |
| // Invoke createAllAssetsDirectory(), the method under test. |
| Optional<Path> allAssetsDirectory = aaptPackageResources.createAllAssetsDirectory( |
| assetsDirectories, commands, filesystem); |
| EasyMock.verify(resourcesFilter); |
| |
| // Verify that an assets/ directory will be created and passed to aapt. |
| assertTrue(allAssetsDirectory.isPresent()); |
| assertEquals(BIN_PATH.resolve("facebook/base/__assets_apk#aapt_package__"), |
| allAssetsDirectory.get()); |
| |
| List<? extends Step> observedCommands = commands.build(); |
| assertEquals(4, observedCommands.size()); |
| assertEquals( |
| new MakeCleanDirectoryStep(BIN_PATH.resolve("facebook/base/__assets_apk#aapt_package__")), |
| observedCommands.get(0)); |
| |
| ImmutableSet<Step> remainingCommands = ImmutableSet.copyOf(observedCommands.subList(1, 4)); |
| MoreAsserts.assertSetEquals( |
| ImmutableSet.<Step>of( |
| new MkdirAndSymlinkFileStep( |
| Paths.get("facebook/base/assets1/guava-10.0.1-fork.dex.1.jar"), |
| BIN_PATH.resolve( |
| "facebook/base/__assets_apk#aapt_package__/guava-10.0.1-fork.dex.1.jar")), |
| new MkdirAndSymlinkFileStep( |
| Paths.get("facebook/base/assets2/fonts/Theinhardt-Medium.otf"), |
| BIN_PATH.resolve( |
| "facebook/base/__assets_apk#aapt_package__/fonts/Theinhardt-Medium.otf")), |
| new MkdirAndSymlinkFileStep( |
| Paths.get("facebook/base/assets2/fonts/Theinhardt-Regular.otf"), |
| BIN_PATH.resolve( |
| "facebook/base/__assets_apk#aapt_package__/fonts/Theinhardt-Regular.otf"))), |
| remainingCommands); |
| } |
| } |