// Path: src/main/java/com/google/devtools/build/bfg/GraphProcessor.java
// static class GraphProcessorException extends RuntimeException {
//   GraphProcessorException(String message) {
//     super(message);
//   }
// }


import static com.google.common.truth.Truth.assertThat;
import static junit.framework.TestCase.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.graph.EndpointPair;
import com.google.common.graph.Graph;
import com.google.common.graph.GraphBuilder;
import com.google.common.graph.ImmutableGraph;
import com.google.common.graph.MutableGraph;
import com.google.devtools.build.bfg.GraphProcessor.GraphProcessorException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
   * Tests behavior when a class is mapped to multiple build rules. The Graph Processor should
   * ignore the mapping of the secondary resolver. This also tests whether the resolvers are called
   * in an appropriate fashion. The first resolver should be called on the entire class graph. The
   * second resolver should be called on an empty set. If it is called on any other argument, then
   * this test will throw either a GraphProcessorException or a NullPointerException.
   */
  @Test
  public void multipleResolversWithDifferingResolutions() {
    MutableGraph<String> classgraph = GraphBuilder.directed().allowsSelfLoops(false).build();
    classgraph.putEdge("com.A", "com.B");

    GraphProcessor processor = new GraphProcessor(ImmutableGraph.copyOf(classgraph));

    String packagePath = "/java/com/";
    BuildRule ruleA = newBuildRule(packagePath, "/java/com/A.java");
    BuildRule ruleB = newBuildRule(packagePath, "/java/com/B.java");
    ClassToRuleResolver resolver1 = mock(ClassToRuleResolver.class);
    when(resolver1.resolve(classgraph.nodes()))
        .thenReturn(ImmutableMap.of("com.A", ruleA, "com.B", ruleB));

    ClassToRuleResolver resolver2 = mock(ClassToRuleResolver.class);
    when(resolver2.resolve(classgraph.nodes())).thenReturn(ImmutableMap.of("com.B", ruleA));
    when(resolver2.resolve(ImmutableSet.of())).thenReturn(ImmutableMap.of());

    try {
      Graph<BuildRule> actual =
          processor.createBuildRuleDAG(ImmutableList.of(resolver1, resolver2));
      MutableGraph<BuildRule> expected = GraphBuilder.directed().allowsSelfLoops(false).build();
      expected.putEdge(ruleA, ruleB);
      assertThatGraphsEqual(actual, expected);
// Path: src/main/java/com/google/devtools/build/bfg/GraphProcessor.java
// static class GraphProcessorException extends RuntimeException {
//   GraphProcessorException(String message) {
//     super(message);
//   }
// }


// Path: src/test/java/com/google/devtools/build/bfg/GraphProcessorTest.java
import static com.google.common.truth.Truth.assertThat;
import static junit.framework.TestCase.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.graph.EndpointPair;
import com.google.common.graph.Graph;
import com.google.common.graph.GraphBuilder;
import com.google.common.graph.ImmutableGraph;
import com.google.common.graph.MutableGraph;
import com.google.devtools.build.bfg.GraphProcessor.GraphProcessorException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

   * Tests behavior when a class is mapped to multiple build rules. The Graph Processor should
   * ignore the mapping of the secondary resolver. This also tests whether the resolvers are called
   * in an appropriate fashion. The first resolver should be called on the entire class graph. The
   * second resolver should be called on an empty set. If it is called on any other argument, then
   * this test will throw either a GraphProcessorException or a NullPointerException.
   */
  @Test
  public void multipleResolversWithDifferingResolutions() {
    MutableGraph<String> classgraph = GraphBuilder.directed().allowsSelfLoops(false).build();
    classgraph.putEdge("com.A", "com.B");

    GraphProcessor processor = new GraphProcessor(ImmutableGraph.copyOf(classgraph));

    String packagePath = "/java/com/";
    BuildRule ruleA = newBuildRule(packagePath, "/java/com/A.java");
    BuildRule ruleB = newBuildRule(packagePath, "/java/com/B.java");
    ClassToRuleResolver resolver1 = mock(ClassToRuleResolver.class);
    when(resolver1.resolve(classgraph.nodes()))
        .thenReturn(ImmutableMap.of("com.A", ruleA, "com.B", ruleB));

    ClassToRuleResolver resolver2 = mock(ClassToRuleResolver.class);
    when(resolver2.resolve(classgraph.nodes())).thenReturn(ImmutableMap.of("com.B", ruleA));
    when(resolver2.resolve(ImmutableSet.of())).thenReturn(ImmutableMap.of());

    try {
      Graph<BuildRule> actual =
          processor.createBuildRuleDAG(ImmutableList.of(resolver1, resolver2));
      MutableGraph<BuildRule> expected = GraphBuilder.directed().allowsSelfLoops(false).build();
      expected.putEdge(ruleA, ruleB);
      assertThatGraphsEqual(actual, expected);
    } catch (GraphProcessorException e) {