@Test
public void allFilesInSameDirAreOnACycle() throws IOException {

  Path x = workspace.resolve("x/");
  Path y = workspace.resolve("y/");
  Path z = workspace.resolve("z/");
  Files.createDirectories(x);
  Files.createDirectories(y);
  Files.createDirectories(z);
  Files.createDirectories(workspace.resolve("tests/"));
  writeFile(workspace.resolve("x/A.java"), "package x; class A {}");
  writeFile(workspace.resolve("y/A.java"), "package y; class A {}");
  writeFile(workspace.resolve("y/B.java"), "package y; class B {}");
  writeFile(workspace.resolve("z/A.java"), "package z; class A {}");
  writeFile(workspace.resolve("z/B.java"), "package z; class B {}");
  writeFile(workspace.resolve("z/C.java"), "package z; class C {}");
  writeFile(workspace.resolve("tests/A.java"), "package tests; class A {}");
  writeFile(workspace.resolve("tests/B.java"), "package tests; class B {}");
  ImmutableList<Path> contentRoots = ImmutableList.of(workspace.resolve(""));
  JavaSourceFileParser parser =
      new JavaSourceFileParser(
          ImmutableList.of(
              workspace.resolve("./x/A.java"),
              workspace.resolve("./y/A.java"),
              workspace.resolve("./y/B.java"),
              workspace.resolve("./z/A.java"),
              workspace.resolve("./z/B.java"),
              workspace.resolve("./z/C.java"),
              workspace.resolve("./tests/A.java"),
              workspace.resolve("./tests/B.java")),
          contentRoots,
          ImmutableSet.of(x, y, z) /* oneRulePerPackageRoots */);
  ImmutableGraph<String> actual = parser.getClassToClass();
  MutableGraph<String> expected = newGraph();
  expected.putEdge("y.A", "y.B");
  expected.putEdge("y.B", "y.A");
  expected.putEdge("z.A", "z.B");
  expected.putEdge("z.B", "z.C");
  expected.putEdge("z.C", "z.A");
  // Implicit: there's no tests.A and tests.B here, because 'tests/' is not in
  // oneRulePerPackageRoots.
  assertThatGraphsEqual(actual, expected);
}