blob: 84216862e4dfe301f73d7a1feeeac75bfbc0977f [file] [log] [blame]
/*
* Copyright 2014-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.rules;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import com.facebook.buck.io.ProjectFilesystem;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.BuildTargetFactory;
import com.facebook.buck.shell.Genrule;
import com.facebook.buck.shell.GenruleBuilder;
import com.facebook.buck.testutil.FakeProjectFilesystem;
import com.facebook.buck.testutil.MoreAsserts;
import com.facebook.buck.util.HumanReadableException;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import org.junit.Test;
import java.nio.file.Path;
import java.nio.file.Paths;
public class SourcePathResolverTest {
@Test
public void resolvePathSourcePath() {
ProjectFilesystem projectFilesystem = new FakeProjectFilesystem();
SourcePathResolver pathResolver = new SourcePathResolver(new BuildRuleResolver());
Path expectedPath = Paths.get("foo");
SourcePath sourcePath = new PathSourcePath(projectFilesystem, expectedPath);
assertEquals(expectedPath, pathResolver.getPath(sourcePath));
}
@Test
public void resolveBuildTargetSourcePath() {
ProjectFilesystem projectFilesystem = new FakeProjectFilesystem();
BuildRuleResolver resolver = new BuildRuleResolver();
SourcePathResolver pathResolver = new SourcePathResolver(resolver);
Path expectedPath = Paths.get("foo");
BuildRule rule = new OutputOnlyBuildRule(
new FakeBuildRuleParamsBuilder(BuildTargetFactory.newInstance("//:foo")).build(),
pathResolver,
expectedPath);
resolver.addToIndex(rule);
SourcePath sourcePath = new BuildTargetSourcePath(projectFilesystem, rule.getBuildTarget());
assertEquals(expectedPath, pathResolver.getPath(sourcePath));
}
@Test
public void resolveBuildTargetSourcePathWithOverriddenOutputPath() {
ProjectFilesystem projectFilesystem = new FakeProjectFilesystem();
BuildRuleResolver resolver = new BuildRuleResolver();
SourcePathResolver pathResolver = new SourcePathResolver(resolver);
Path expectedPath = Paths.get("foo");
BuildRule rule = new OutputOnlyBuildRule(
new FakeBuildRuleParamsBuilder(BuildTargetFactory.newInstance("//:foo")).build(),
pathResolver,
Paths.get("notfoo"));
resolver.addToIndex(rule);
SourcePath sourcePath = new BuildTargetSourcePath(
projectFilesystem,
rule.getBuildTarget(),
expectedPath);
assertEquals(expectedPath, pathResolver.getPath(sourcePath));
}
@Test
public void resolveMixedPaths() {
ProjectFilesystem projectFilesystem = new FakeProjectFilesystem();
BuildRuleResolver resolver = new BuildRuleResolver();
SourcePathResolver pathResolver = new SourcePathResolver(resolver);
Path pathSourcePathExpectedPath = Paths.get("foo");
Path buildTargetSourcePathExpectedPath = Paths.get("bar");
Path buildRuleWithOverriddenOutputPathExpectedPath = Paths.get("baz");
SourcePath pathSourcePath = new PathSourcePath(projectFilesystem, pathSourcePathExpectedPath);
BuildRule rule = new OutputOnlyBuildRule(
new FakeBuildRuleParamsBuilder(BuildTargetFactory.newInstance("//:bar")).build(),
pathResolver,
buildTargetSourcePathExpectedPath);
resolver.addToIndex(rule);
SourcePath buildTargetSourcePath = new BuildTargetSourcePath(
projectFilesystem,
rule.getBuildTarget());
BuildRule ruleWithOverriddenOutputPath = new OutputOnlyBuildRule(
new FakeBuildRuleParamsBuilder(BuildTargetFactory.newInstance("//:baz")).build(),
pathResolver,
Paths.get("notbaz"));
resolver.addToIndex(ruleWithOverriddenOutputPath);
SourcePath buildTargetSourcePathWithOverriddenOutputPath = new BuildTargetSourcePath(
projectFilesystem,
ruleWithOverriddenOutputPath.getBuildTarget(),
buildRuleWithOverriddenOutputPathExpectedPath);
assertEquals(
ImmutableList.of(
pathSourcePathExpectedPath,
buildTargetSourcePathExpectedPath,
buildRuleWithOverriddenOutputPathExpectedPath),
pathResolver.getAllPaths(
ImmutableList.of(
pathSourcePath,
buildTargetSourcePath,
buildTargetSourcePathWithOverriddenOutputPath)));
}
@Test
public void getRuleCanGetRuleOfBuildRuleSoucePath() {
ProjectFilesystem projectFilesystem = new FakeProjectFilesystem();
BuildRuleResolver resolver = new BuildRuleResolver();
SourcePathResolver pathResolver = new SourcePathResolver(resolver);
BuildRule rule = new OutputOnlyBuildRule(
new FakeBuildRuleParamsBuilder(BuildTargetFactory.newInstance("//:foo")).build(),
pathResolver,
Paths.get("foo"));
resolver.addToIndex(rule);
SourcePath sourcePath = new BuildTargetSourcePath(projectFilesystem, rule.getBuildTarget());
assertEquals(Optional.of(rule), pathResolver.getRule(sourcePath));
}
@Test
public void getRuleCannotGetRuleOfPathSoucePath() {
ProjectFilesystem projectFilesystem = new FakeProjectFilesystem();
SourcePathResolver pathResolver = new SourcePathResolver(new BuildRuleResolver());
SourcePath sourcePath = new PathSourcePath(projectFilesystem, Paths.get("foo"));
assertEquals(Optional.<BuildRule>absent(), pathResolver.getRule(sourcePath));
}
@Test
public void getRelativePathCanGetRelativePathOfPathSourcePath() {
ProjectFilesystem projectFilesystem = new FakeProjectFilesystem();
SourcePathResolver pathResolver = new SourcePathResolver(new BuildRuleResolver());
Path expectedPath = Paths.get("foo");
SourcePath sourcePath = new PathSourcePath(projectFilesystem, expectedPath);
assertEquals(Optional.of(expectedPath), pathResolver.getRelativePath(sourcePath));
}
@Test
public void getRelativePathCannotGetRelativePathOfBuildTargetSourcePath() {
ProjectFilesystem projectFilesystem = new FakeProjectFilesystem();
BuildRuleResolver resolver = new BuildRuleResolver();
SourcePathResolver pathResolver = new SourcePathResolver(resolver);
BuildRule rule = new OutputOnlyBuildRule(
new FakeBuildRuleParamsBuilder(BuildTargetFactory.newInstance("//:foo")).build(),
pathResolver,
Paths.get("foo"));
resolver.addToIndex(rule);
SourcePath sourcePath = new BuildTargetSourcePath(projectFilesystem, rule.getBuildTarget());
assertEquals(Optional.<Path>absent(), pathResolver.getRelativePath(sourcePath));
}
@Test
public void testEmptyListAsInputToFilterInputsToCompareToOutput() {
Iterable<SourcePath> sourcePaths = ImmutableList.of();
Iterable<Path> inputs = new SourcePathResolver(
new BuildRuleResolver()).filterInputsToCompareToOutput(sourcePaths);
MoreAsserts.assertIterablesEquals(ImmutableList.<String>of(), inputs);
}
@Test
public void testFilterInputsToCompareToOutputExcludesBuildTargetSourcePaths() {
ProjectFilesystem projectFilesystem = new FakeProjectFilesystem();
BuildRuleResolver resolver = new BuildRuleResolver();
SourcePathResolver pathResolver = new SourcePathResolver(resolver);
FakeBuildRule rule = new FakeBuildRule(
ImmutableBuildRuleType.of("example"),
BuildTargetFactory.newInstance("//java/com/facebook:facebook"),
pathResolver);
resolver.addToIndex(rule);
Iterable<? extends SourcePath> sourcePaths = ImmutableList.of(
new TestSourcePath("java/com/facebook/Main.java"),
new TestSourcePath("java/com/facebook/BuckConfig.java"),
new BuildTargetSourcePath(projectFilesystem, rule.getBuildTarget()));
Iterable<Path> inputs = pathResolver.filterInputsToCompareToOutput(sourcePaths);
MoreAsserts.assertIterablesEquals(
"Iteration order should be preserved: results should not be alpha-sorted.",
ImmutableList.of(
Paths.get("java/com/facebook/Main.java"),
Paths.get("java/com/facebook/BuckConfig.java")),
inputs);
}
@Test
public void testFilterBuildRuleInputsExcludesPathSourcePaths() {
ProjectFilesystem projectFilesystem = new FakeProjectFilesystem();
BuildRuleResolver resolver = new BuildRuleResolver();
SourcePathResolver pathResolver = new SourcePathResolver(resolver);
FakeBuildRule rule = new FakeBuildRule(
ImmutableBuildRuleType.of("example"),
BuildTargetFactory.newInstance("//java/com/facebook:facebook"),
pathResolver);
resolver.addToIndex(rule);
FakeBuildRule rule2 = new FakeBuildRule(
ImmutableBuildRuleType.of("foo"),
BuildTargetFactory.newInstance("//bar:foo"),
pathResolver);
resolver.addToIndex(rule2);
Iterable<? extends SourcePath> sourcePaths = ImmutableList.of(
new TestSourcePath("java/com/facebook/Main.java"),
new BuildTargetSourcePath(projectFilesystem, rule.getBuildTarget()),
new TestSourcePath("java/com/facebook/BuckConfig.java"),
new BuildTargetSourcePath(projectFilesystem, rule2.getBuildTarget()));
Iterable<BuildRule> inputs = pathResolver.filterBuildRuleInputs(sourcePaths);
MoreAsserts.assertIterablesEquals(
"Iteration order should be preserved: results should not be alpha-sorted.",
ImmutableList.of(
rule,
rule2),
inputs);
}
@Test
public void getSourcePathNameOnPathSourcePath() {
ProjectFilesystem projectFilesystem = new FakeProjectFilesystem();
Path path = Paths.get("hello/world.txt");
// Test that constructing a PathSourcePath without an explicit name resolves to the
// string representation of the path.
PathSourcePath pathSourcePath1 = new PathSourcePath(projectFilesystem, path);
String actual1 = new SourcePathResolver(new BuildRuleResolver()).getSourcePathName(
BuildTargetFactory.newInstance("//:test"),
pathSourcePath1);
assertEquals(path.toString(), actual1);
}
@Test
public void getSourcePathNameOnBuildTargetSourcePath() {
ProjectFilesystem projectFilesystem = new FakeProjectFilesystem();
BuildRuleResolver resolver = new BuildRuleResolver();
SourcePathResolver pathResolver = new SourcePathResolver(resolver);
// Verify that wrapping a genrule in a BuildTargetSourcePath resolves to the output name of
// that genrule.
String out = "test/blah.txt";
Genrule genrule = (Genrule) GenruleBuilder
.newGenruleBuilder(BuildTargetFactory.newInstance("//:genrule"))
.setOut(out)
.build(resolver);
BuildTargetSourcePath buildTargetSourcePath1 = new BuildTargetSourcePath(
projectFilesystem,
genrule.getBuildTarget());
String actual1 = pathResolver.getSourcePathName(
BuildTargetFactory.newInstance("//:test"),
buildTargetSourcePath1);
assertEquals(out, actual1);
// Test that using other BuildRule types resolves to the short name.
BuildTarget fakeBuildTarget = BuildTargetFactory.newInstance("//:fake");
FakeBuildRule fakeBuildRule = new FakeBuildRule(
new FakeBuildRuleParamsBuilder(fakeBuildTarget).build(),
pathResolver);
resolver.addToIndex(fakeBuildRule);
BuildTargetSourcePath buildTargetSourcePath2 = new BuildTargetSourcePath(
projectFilesystem,
fakeBuildRule.getBuildTarget());
String actual2 = pathResolver.getSourcePathName(
BuildTargetFactory.newInstance("//:test"),
buildTargetSourcePath2);
assertEquals(fakeBuildTarget.getShortName(), actual2);
}
@Test
public void getSourcePathNamesThrowsOnDuplicates() {
ProjectFilesystem projectFilesystem = new FakeProjectFilesystem();
BuildTarget target = BuildTargetFactory.newInstance("//:test");
String parameter = "srcs";
PathSourcePath pathSourcePath1 = new PathSourcePath(projectFilesystem, Paths.get("same_name"));
PathSourcePath pathSourcePath2 = new PathSourcePath(projectFilesystem, Paths.get("same_name"));
// Try to resolve these source paths, with the same name, together and verify that an
// exception is thrown.
try {
new SourcePathResolver(new BuildRuleResolver()).getSourcePathNames(
target,
parameter,
ImmutableList.<SourcePath>of(pathSourcePath1, pathSourcePath2));
fail("expected to throw");
} catch (HumanReadableException e) {
assertTrue(e.getMessage().contains("duplicate entries"));
}
}
}