/*
* 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 com.facebook.buck.rules.TestCellBuilder.createCellRoots;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import com.facebook.buck.io.ProjectFilesystem;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.BuildTargetFactory;
import com.facebook.buck.parser.NoSuchBuildTargetException;
import com.facebook.buck.rules.coercer.ConstructorArgMarshaller;
import com.facebook.buck.rules.coercer.DefaultTypeCoercerFactory;
import com.facebook.buck.rules.coercer.ParamInfoException;
import com.facebook.buck.testutil.FakeProjectFilesystem;
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 com.google.common.hash.Hashing;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
import java.util.Optional;
import org.junit.Test;
public class TargetNodeTest {
public static final BuildTarget TARGET_THREE =
BuildTargetFactory.newInstance("//example/path:three");
@Test
public void testIgnoreNonBuildTargetOrPathOrSourcePathArgument()
throws NoSuchBuildTargetException {
TargetNode<Arg, ExampleDescription> targetNode = createTargetNode(TARGET_THREE);
assertTrue(targetNode.getExtraDeps().isEmpty());
assertTrue(targetNode.getDeclaredDeps().isEmpty());
}
@Test
public void testDepsAndPathsAreCollected() throws NoSuchBuildTargetException {
ImmutableList<String> depsStrings =
ImmutableList.of("//example/path:one", "//example/path:two");
ImmutableSet<BuildTarget> depsTargets =
depsStrings
.stream()
.map(BuildTargetFactory::newInstance)
.collect(MoreCollectors.toImmutableSet());
ImmutableMap<String, Object> rawNode =
ImmutableMap.of(
"deps",
depsStrings,
"sourcePaths",
ImmutableList.of("//example/path:four", "MyClass.java"),
"appleSource",
"//example/path:five",
"source",
"AnotherClass.java");
TargetNode<Arg, ExampleDescription> targetNode =
createTargetNode(TARGET_THREE, depsTargets, rawNode);
assertThat(
targetNode.getInputs(),
containsInAnyOrder(
Paths.get("example/path/MyClass.java"), Paths.get("example/path/AnotherClass.java")));
assertThat(
targetNode.getExtraDeps(),
containsInAnyOrder(
BuildTargetFactory.newInstance("//example/path:four"),
BuildTargetFactory.newInstance("//example/path:five")));
assertThat(
targetNode.getDeclaredDeps(),
containsInAnyOrder(
BuildTargetFactory.newInstance("//example/path:one"),
BuildTargetFactory.newInstance("//example/path:two")));
}
@Test
public void targetsWithTheSameRelativePathButNotTheSameCellMightNotBeAbleToSeeEachOther()
throws Exception {
ProjectFilesystem rootOne = FakeProjectFilesystem.createJavaOnlyFilesystem("/one");
BuildTarget buildTargetOne = BuildTargetFactory.newInstance(rootOne.getRootPath(), "//foo:bar");
TargetNode<Arg, ExampleDescription> targetNodeOne = createTargetNode(buildTargetOne);
ProjectFilesystem rootTwo = FakeProjectFilesystem.createJavaOnlyFilesystem("/two");
BuildTarget buildTargetTwo = BuildTargetFactory.newInstance(rootTwo.getRootPath(), "//foo:bar");
TargetNode<Arg, ExampleDescription> targetNodeTwo = createTargetNode(buildTargetTwo);
boolean isVisible = targetNodeOne.isVisibleTo(targetNodeTwo);
assertThat(isVisible, is(false));
}
public static class Arg extends AbstractDescriptionArg {
public ImmutableSortedSet<BuildTarget> deps;
public ImmutableSortedSet<SourcePath> sourcePaths;
public Optional<SourceWithFlags> appleSource;
public Optional<Path> source;
public Optional<String> string;
@Hint(isDep = false)
public Optional<BuildTarget> target;
}
public static class ExampleDescription implements Description<Arg> {
@Override
public Class<Arg> getConstructorArgType() {
return Arg.class;
}
@Override
public BuildRule createBuildRule(
TargetGraph targetGraph,
BuildRuleParams params,
BuildRuleResolver resolver,
CellPathResolver cellRoots,
Arg args) {
return new FakeBuildRule(params, new SourcePathResolver(new SourcePathRuleFinder(resolver)));
}
}
private static TargetNode<Arg, ExampleDescription> createTargetNode(BuildTarget buildTarget)
throws NoSuchBuildTargetException {
ImmutableMap<String, Object> rawNode =
ImmutableMap.of(
"deps",
ImmutableList.of(),
"string",
"//example/path:one",
"target",
"//example/path:two",
"sourcePaths",
ImmutableSortedSet.of());
return createTargetNode(buildTarget, ImmutableSet.of(), rawNode);
}
private static TargetNode<Arg, ExampleDescription> createTargetNode(
BuildTarget buildTarget,
ImmutableSet<BuildTarget> declaredDeps,
ImmutableMap<String, Object> rawNode)
throws NoSuchBuildTargetException {
FakeProjectFilesystem filesystem = new FakeProjectFilesystem();
ExampleDescription description = new ExampleDescription();
return new TargetNodeFactory(new DefaultTypeCoercerFactory())
.create(
Hashing.sha1().hashString(buildTarget.getFullyQualifiedName(), UTF_8),
description,
createPopulatedConstructorArg(buildTarget, rawNode),
filesystem,
buildTarget,
declaredDeps,
ImmutableSet.of(),
ImmutableSet.of(),
createCellRoots(filesystem));
}
private static Arg createPopulatedConstructorArg(
BuildTarget buildTarget, Map<String, Object> instance) throws NoSuchBuildTargetException {
ConstructorArgMarshaller marshaller =
new ConstructorArgMarshaller(new DefaultTypeCoercerFactory());
ProjectFilesystem projectFilesystem = new FakeProjectFilesystem();
try {
return marshaller.populate(
createCellRoots(projectFilesystem),
projectFilesystem,
buildTarget,
Arg.class,
ImmutableSet.builder(),
instance);
} catch (ParamInfoException e) {
throw new RuntimeException(e);
}
}
}