blob: 09b94774fd1844d57db15915e13d962aee63eeb2 [file] [log] [blame]
/*
* Copyright 2012-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 com.facebook.buck.java.FakeJavaLibraryRule;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.BuildTargetPattern;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import org.junit.Test;
import java.util.List;
public class AbstractDependencyVisitorTest {
private static final String BUILD_RULE_BASE_NAME = "//java";
@Test
public void testIsBreadthFirst() {
// The dependency graph of build rules being built up is as follows:
//
// J
// / / \ \
// F G H I
// / \ / \ \
// E D C B A
//
BuildRule ruleA = createRule("A");
BuildRule ruleB = createRule("B");
BuildRule ruleC = createRule("C");
BuildRule ruleD = createRule("D");
BuildRule ruleE = createRule("E");
BuildRule ruleF = createRule("F", ruleE, ruleD);
BuildRule ruleG = createRule("G");
BuildRule ruleH = createRule("H", ruleC, ruleB);
BuildRule ruleI = createRule("I", ruleA);
BuildRule initialRule = createRule("J", ruleF, ruleG, ruleH, ruleI);
final List<BuildRule> buildRuleTraversalOrder = Lists.newArrayList();
new AbstractDependencyVisitor(initialRule) {
@Override
public ImmutableSet<BuildRule> visit(BuildRule rule) {
buildRuleTraversalOrder.add(rule);
return rule.getDeps();
}
}.start();
assertEquals(
"Dependencies should be explored depth-first, using lexicographic ordering to break ties",
ImmutableList.of(initialRule,
ruleF,
ruleG,
ruleH,
ruleI,
ruleD,
ruleE,
ruleB,
ruleC,
ruleA),
buildRuleTraversalOrder);
}
@Test
public void testSubsetWorks() {
// The dependency graph of build rules being built up is as follows:
//
// 10
// / / \ \
// 6 7 8 9
// / \ / \ \
// 5 4 3 2 1
//
BuildRule rule1 = createRule("1");
BuildRule rule2 = createRule("2");
BuildRule rule3 = createRule("3");
BuildRule rule4 = createRule("4");
BuildRule rule5 = createRule("5");
BuildRule rule6 = createRule("6", rule5, rule4);
BuildRule rule7 = createRule("7");
BuildRule rule8 = createRule("8", rule3, rule2);
BuildRule rule9 = createRule("9", rule1);
BuildRule initialRule = createRule("10", rule6, rule7, rule8, rule9);
final List<BuildRule> buildRuleTraversalOrder = Lists.newArrayList();
// This visitor only visits dependencies whose node names are even numbers.
new AbstractDependencyVisitor(initialRule) {
@Override
public ImmutableSet<BuildRule> visit(BuildRule rule) {
buildRuleTraversalOrder.add(rule);
return ImmutableSet.copyOf(Iterables.filter(rule.getDeps(), new Predicate<BuildRule>() {
@Override
public boolean apply(BuildRule input) {
return Integer.parseInt(input.getBuildTarget().getShortName()) % 2 == 0;
}
}));
}
}.start();
assertEquals(
"Dependencies should be explored depth-first, only containing rules whose rule name is " +
"an even number",
ImmutableList.of(initialRule,
rule6,
rule8,
rule4,
rule2),
buildRuleTraversalOrder);
}
private FakeJavaLibraryRule createRule(String name, BuildRule... deps) {
ImmutableSet<BuildTargetPattern> visibilityPatterns = ImmutableSet.of();
FakeJavaLibraryRule rule = new FakeJavaLibraryRule(
BuildRuleType.JAVA_LIBRARY,
new BuildTarget(BUILD_RULE_BASE_NAME, name),
ImmutableSortedSet.copyOf(deps),
visibilityPatterns);
return rule;
}
}