Example #1
0
  @Test
  public void testThatBuildTargetSourcePathDepsAndPathsArePropagated() {
    BuildRuleResolver resolver = new BuildRuleResolver();
    BuildTarget target = BuildTargetFactory.newInstance("//foo:bar");
    BuildRuleParams params = BuildRuleParamsFactory.createTrivialBuildRuleParams(target);

    // Create a couple of genrules to generate inputs for an archive rule.
    Genrule genrule1 =
        (Genrule)
            GenruleBuilder.newGenruleBuilder(BuildTargetFactory.newInstance("//:genrule"))
                .setOut("foo/bar.o")
                .build(resolver);
    Genrule genrule2 =
        (Genrule)
            GenruleBuilder.newGenruleBuilder(BuildTargetFactory.newInstance("//:genrule2"))
                .setOut("foo/test.o")
                .build(resolver);

    // Build the archive using a normal input the outputs of the genrules above.
    Archive archive =
        Archives.createArchiveRule(
            new SourcePathResolver(resolver),
            target,
            params,
            DEFAULT_ARCHIVER,
            DEFAULT_OUTPUT,
            ImmutableList.<SourcePath>of(
                new TestSourcePath("simple.o"),
                new BuildTargetSourcePath(genrule1.getBuildTarget()),
                new BuildTargetSourcePath(genrule2.getBuildTarget())));

    // Verify that the archive dependencies include the genrules providing the
    // SourcePath inputs.
    assertEquals(ImmutableSortedSet.<BuildRule>of(genrule1, genrule2), archive.getDeps());
  }
  @Test
  public void ruleKeyDoesNotChangeWhenOnlyDependencyRuleKeyChanges() throws Exception {
    ProjectFilesystem filesystem = new FakeProjectFilesystem();
    BuildRuleResolver resolver =
        new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer());
    SourcePathResolver pathResolver = new SourcePathResolver(resolver);

    Path depOutput = Paths.get("output");
    FakeBuildRule dep =
        resolver.addToIndex(
            new FakeBuildRule(BuildTargetFactory.newInstance("//:dep"), filesystem, pathResolver));
    dep.setOutputFile(depOutput.toString());
    filesystem.writeContentsToPath("hello", dep.getPathToOutput());

    FakeFileHashCache hashCache =
        new FakeFileHashCache(ImmutableMap.of(filesystem.resolve(depOutput), HashCode.fromInt(0)));

    BuildRule rule =
        GenruleBuilder.newGenruleBuilder(BuildTargetFactory.newInstance("//:rule"))
            .setOut("out")
            .setSrcs(ImmutableList.<SourcePath>of(new BuildTargetSourcePath(dep.getBuildTarget())))
            .build(resolver, filesystem);

    RuleKey inputKey1 = new InputBasedRuleKeyBuilderFactory(0, hashCache, pathResolver).build(rule);

    RuleKey inputKey2 = new InputBasedRuleKeyBuilderFactory(0, hashCache, pathResolver).build(rule);

    assertThat(inputKey1, Matchers.equalTo(inputKey2));
  }
Example #3
0
  @Test
  public void testPathsUnderDirectories() throws CmdLineException, IOException {
    ProjectFilesystem projectFilesystem = new FakeProjectFilesystem();
    Path resDir = Paths.get("some/resources/dir");
    BuildTarget androidResourceTarget = BuildTargetFactory.newInstance("//:res");
    TargetNode<?> androidResourceNode =
        AndroidResourceBuilder.createBuilder(androidResourceTarget).setRes(resDir).build();

    Path genSrc = resDir.resolve("foo.txt");
    BuildTarget genTarget = BuildTargetFactory.newInstance("//:res");
    TargetNode<?> genNode =
        GenruleBuilder.newGenruleBuilder(genTarget)
            .setSrcs(ImmutableList.<SourcePath>of(new PathSourcePath(projectFilesystem, genSrc)))
            .build();

    TargetGraph targetGraph = TargetGraphFactory.newInstance(androidResourceNode, genNode);

    SortedMap<String, TargetNode<?>> matchingBuildRules;

    // Specifying a resource under the resource directory causes a match.
    matchingBuildRules =
        targetsCommand.getMatchingNodes(
            targetGraph,
            Optional.of(ImmutableSet.of(resDir.resolve("some_resource.txt"))),
            Optional.<ImmutableSet<BuildTarget>>absent(),
            Optional.<ImmutableSet<BuildRuleType>>absent(),
            false,
            "BUCK");
    assertEquals(ImmutableSet.of(androidResourceTarget.toString()), matchingBuildRules.keySet());

    // Specifying a resource with the same string-like common prefix, but not under the above
    // resource dir, should not trigger a match.
    matchingBuildRules =
        targetsCommand.getMatchingNodes(
            targetGraph,
            Optional.of(
                ImmutableSet.of(
                    Paths.get(resDir.toString() + "_extra").resolve("some_resource.txt"))),
            Optional.<ImmutableSet<BuildTarget>>absent(),
            Optional.<ImmutableSet<BuildRuleType>>absent(),
            false,
            "BUCK");
    assertTrue(matchingBuildRules.isEmpty());

    // Specifying a resource with the same string-like common prefix, but not under the above
    // resource dir, should not trigger a match.
    matchingBuildRules =
        targetsCommand.getMatchingNodes(
            targetGraph,
            Optional.of(ImmutableSet.of(genSrc)),
            Optional.<ImmutableSet<BuildTarget>>absent(),
            Optional.<ImmutableSet<BuildRuleType>>absent(),
            false,
            "BUCK");
    assertEquals(
        ImmutableSet.of(androidResourceTarget.toString(), genTarget.toString()),
        matchingBuildRules.keySet());
  }
Example #4
0
  @Test
  public void testThatBuildTargetSourcePathDepsAndPathsArePropagated() throws Exception {
    BuildRuleResolver resolver =
        new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer());
    BuildTarget target = BuildTargetFactory.newInstance("//foo:bar");
    BuildRuleParams params = new FakeBuildRuleParamsBuilder(target).build();

    // Create a couple of genrules to generate inputs for an archive rule.
    Genrule genrule1 =
        (Genrule)
            GenruleBuilder.newGenruleBuilder(BuildTargetFactory.newInstance("//:genrule"))
                .setOut("foo/bar.o")
                .build(resolver);
    Genrule genrule2 =
        (Genrule)
            GenruleBuilder.newGenruleBuilder(BuildTargetFactory.newInstance("//:genrule2"))
                .setOut("foo/test.o")
                .build(resolver);

    // Build the archive using a normal input the outputs of the genrules above.
    Archive archive =
        Archive.from(
            target,
            params,
            new SourcePathResolver(resolver),
            DEFAULT_ARCHIVER,
            ImmutableList.of(),
            DEFAULT_RANLIB,
            ImmutableList.of(),
            Archive.Contents.NORMAL,
            DEFAULT_OUTPUT,
            ImmutableList.of(
                new FakeSourcePath("simple.o"),
                new BuildTargetSourcePath(genrule1.getBuildTarget()),
                new BuildTargetSourcePath(genrule2.getBuildTarget())));

    // Verify that the archive dependencies include the genrules providing the
    // SourcePath inputs.
    assertEquals(ImmutableSortedSet.<BuildRule>of(genrule1, genrule2), archive.getDeps());
  }
  @Test
  public void ruleKeyChangesIfInputContentsFromBuildTargetSourcePathInRuleKeyAppendableChanges()
      throws Exception {
    BuildRuleResolver resolver =
        new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer());
    SourcePathResolver pathResolver = new SourcePathResolver(resolver);
    final FakeProjectFilesystem filesystem = new FakeProjectFilesystem();

    final BuildRule dep =
        GenruleBuilder.newGenruleBuilder(BuildTargetFactory.newInstance("//:dep"))
            .setOut("out")
            .build(resolver, filesystem);

    BuildRuleParams params =
        new FakeBuildRuleParamsBuilder("//:rule")
            .setDeclaredDeps(ImmutableSortedSet.of(dep))
            .setProjectFilesystem(filesystem)
            .build();
    BuildRule rule =
        new NoopBuildRule(params, pathResolver) {
          @AddToRuleKey
          RuleKeyAppendableWithInput input =
              new RuleKeyAppendableWithInput(new BuildTargetSourcePath(dep.getBuildTarget()));
        };

    // Build a rule key with a particular hash set for the output for the above rule.
    FakeFileHashCache hashCache =
        new FakeFileHashCache(
            ImmutableMap.of(
                filesystem.resolve(Preconditions.checkNotNull(dep.getPathToOutput())),
                HashCode.fromInt(0)));

    RuleKey inputKey1 = new InputBasedRuleKeyBuilderFactory(0, hashCache, pathResolver).build(rule);

    // Now, build a rule key with a different hash for the output for the above rule.
    hashCache =
        new FakeFileHashCache(
            ImmutableMap.of(
                filesystem.resolve(Preconditions.checkNotNull(dep.getPathToOutput())),
                HashCode.fromInt(1)));

    RuleKey inputKey2 = new InputBasedRuleKeyBuilderFactory(0, hashCache, pathResolver).build(rule);

    assertThat(inputKey1, Matchers.not(Matchers.equalTo(inputKey2)));
  }
  @Test
  public void createBuildRuleWithFlavoredTargetCallsEnhancerCorrectly() throws IOException {
    BuildRuleResolver resolver = new BuildRuleResolver();
    SourcePathResolver pathResolver = new SourcePathResolver(resolver);
    FakeProjectFilesystem filesystem = new FakeProjectFilesystem();

    // Setup the default values returned by the language specific enhancer.
    String language = "fake";
    Flavor flavor = ImmutableFlavor.of("fake");
    final BuildRule implicitDep = createFakeBuildRule("//implicit:dep", pathResolver);
    resolver.addToIndex(implicitDep);
    filesystem.mkdirs(implicitDep.getBuildTarget().getBasePath());
    filesystem.touch(implicitDep.getBuildTarget().getBasePath().resolve("BUCK"));
    ImmutableSet<BuildTarget> implicitDeps = ImmutableSet.of(implicitDep.getBuildTarget());
    ImmutableSet<String> options = ImmutableSet.of();

    // Create the build targets and params.
    BuildTarget unflavoredTarget = BuildTargetFactory.newInstance("//:thrift");
    BuildRuleParams unflavoredParams =
        new FakeBuildRuleParamsBuilder(unflavoredTarget).setProjectFilesystem(filesystem).build();
    BuildTarget flavoredTarget =
        BuildTargets.createFlavoredBuildTarget(unflavoredTarget.checkUnflavored(), flavor);
    BuildRuleParams flavoredParams =
        new FakeBuildRuleParamsBuilder(flavoredTarget).setProjectFilesystem(filesystem).build();

    // Setup a thrift source file generated by a genrule.
    final String thriftSourceName1 = "foo.thrift";
    BuildTarget genruleTarget = BuildTargetFactory.newInstance("//:genrule");
    final Genrule genrule =
        (Genrule)
            GenruleBuilder.newGenruleBuilder(genruleTarget)
                .setOut(thriftSourceName1)
                .build(resolver);
    SourcePath thriftSource1 = new BuildTargetSourcePath(genrule.getBuildTarget());
    final ImmutableList<String> thriftServices1 = ImmutableList.of();

    // Setup a normal thrift source file.
    final String thriftSourceName2 = "bar.thrift";
    SourcePath thriftSource2 = new TestSourcePath(thriftSourceName2);
    final ImmutableList<String> thriftServices2 = ImmutableList.of();

    // Create a build rule that represents the thrift rule.
    final FakeBuildRule thriftRule = createFakeBuildRule("//thrift:target", pathResolver);
    resolver.addToIndex(thriftRule);
    filesystem.mkdirs(thriftRule.getBuildTarget().getBasePath());
    filesystem.touch(thriftRule.getBuildTarget().getBasePath().resolve("BUCK"));

    // Setup a simple description with an empty config.
    FakeBuckConfig buckConfig =
        new FakeBuckConfig(
            ImmutableMap.of(
                "thrift", ImmutableMap.of("compiler", thriftRule.getBuildTarget().toString())));
    ThriftBuckConfig thriftBuckConfig = new ThriftBuckConfig(buckConfig);
    ThriftLibraryDescription desc =
        new ThriftLibraryDescription(
            thriftBuckConfig, ImmutableList.<ThriftLanguageSpecificEnhancer>of());

    // Setup the include rules.
    final BuildRule thriftIncludeSymlinkTree =
        createFakeBuildRule(
            desc.createThriftIncludeSymlinkTreeTarget(unflavoredTarget), pathResolver);

    // Setup our language enhancer
    FakeThriftLanguageSpecificEnhancer enhancer =
        new FakeThriftLanguageSpecificEnhancer(language, flavor, implicitDeps, options) {
          @Override
          public void checkCreateBuildRuleInputs(
              ImmutableMap<String, ThriftSource> sources, ImmutableSortedSet<BuildRule> deps) {

            // Verify both thrift sources are present in the list.
            assertEquals(2, sources.size());
            ThriftSource src1 = sources.get(thriftSourceName1);
            assertNotNull(src1);
            ThriftSource src2 = sources.get(thriftSourceName2);
            assertNotNull(src2);

            // Verify the services are listed correctly for both sources.
            assertEquals(thriftServices1, src1.getServices());
            assertEquals(thriftServices2, src2.getServices());

            // Verify dependencies are setup correctly.
            assertEquals(
                ImmutableSortedSet.of(genrule, thriftRule, thriftIncludeSymlinkTree),
                src1.getCompileRule().getDeps());
            assertEquals(
                ImmutableSortedSet.of(genrule, thriftRule, thriftIncludeSymlinkTree),
                src2.getCompileRule().getDeps());

            // Verify the language specific implicit rules are added correctly.
            assertEquals(
                ImmutableSortedSet.<BuildRule>naturalOrder().add(implicitDep).build(), deps);
          }
        };

    // Recreate the description with the enhancer we setup above.
    desc =
        new ThriftLibraryDescription(
            thriftBuckConfig, ImmutableList.<ThriftLanguageSpecificEnhancer>of(enhancer));

    // Setup the internal structure indicating that the thrift target was set in the
    // buck config.
    // desc.setCompilerTarget(thriftRule.getBuildTarget());

    // Setup the implicit deps for the flavored build target.
    // desc.setImplicitDeps(flavoredTarget, ImmutableList.of(implicitDep.getBuildTarget()));

    // Build up the constructor arg.
    ThriftConstructorArg arg = desc.createUnpopulatedConstructorArg();
    arg.name = "thrift";
    arg.srcs =
        ImmutableMap.of(
            thriftSource1, thriftServices1,
            thriftSource2, thriftServices2);
    arg.deps = Optional.absent();
    arg.flags = Optional.absent();

    // Setup the unflavored target, which should just produce a ThriftInclude, SymlinkTree, and
    // ThriftLibrary rule.
    BuildRule rule = desc.createBuildRule(TargetGraph.EMPTY, unflavoredParams, resolver, arg);
    resolver.addToIndex(rule);

    // Now attempt to create the flavored thrift library.
    desc.createBuildRule(TargetGraph.EMPTY, flavoredParams, resolver, arg);
  }
  @Test
  public void createThriftCompilerBuildRulesHasCorrectDeps() throws IOException {
    BuildRuleResolver resolver = new BuildRuleResolver();
    SourcePathResolver pathResolver = new SourcePathResolver(resolver);
    FakeProjectFilesystem filesystem = new FakeProjectFilesystem();

    String language = "fake";
    Flavor flavor = ImmutableFlavor.of("fake");
    ImmutableSet<String> options = ImmutableSet.of();

    // Setup the default values returned by the language specific enhancer.
    BuildTarget unflavoredTarget = BuildTargetFactory.newInstance("//:thrift");
    BuildRuleParams unflavoredParams =
        new FakeBuildRuleParamsBuilder(BuildTarget.builder(unflavoredTarget).build())
            .setProjectFilesystem(filesystem)
            .build();

    // Setup a thrift source file generated by a genrule.
    BuildTarget flavoredTarget =
        BuildTargets.createFlavoredBuildTarget(unflavoredTarget.checkUnflavored(), flavor);
    BuildRuleParams flavoredParams =
        new FakeBuildRuleParamsBuilder(flavoredTarget).setProjectFilesystem(filesystem).build();

    // Create a path for the thrift compiler.
    Path thriftPath = Paths.get("thrift_path");
    filesystem.touch(thriftPath);

    // Setup an thrift buck config, with the path to the thrift compiler set.
    FakeBuckConfig buckConfig =
        new FakeBuckConfig(
            ImmutableMap.of("thrift", ImmutableMap.of("compiler", thriftPath.toString())),
            filesystem);
    ThriftBuckConfig thriftBuckConfig = new ThriftBuckConfig(buckConfig);
    ThriftLibraryDescription desc =
        new ThriftLibraryDescription(
            thriftBuckConfig, ImmutableList.<ThriftLanguageSpecificEnhancer>of());

    // Setup a simple thrift source.
    String sourceName = "test.thrift";
    SourcePath sourcePath = new TestSourcePath(sourceName);

    // Generate these rules using no deps.
    ImmutableMap<String, ThriftCompiler> rules =
        desc.createThriftCompilerBuildRules(
            flavoredParams,
            resolver,
            ThriftLibraryDescription.CompilerType.THRIFT,
            ImmutableList.<String>of(),
            language,
            options,
            ImmutableMap.of(sourceName, sourcePath),
            ImmutableSortedSet.<ThriftLibrary>of());

    // Now verify that the generated rule had no associated deps.
    assertSame(rules.size(), 1);
    ThriftCompiler rule = rules.get(sourceName);
    assertNotNull(rule);
    assertEquals(ImmutableSortedSet.<BuildRule>of(), rule.getDeps());

    // Lets do this again, but pass in a ThriftLibrary deps, wrapping some includes we need.
    Path includeRoot = desc.getIncludeRoot(unflavoredTarget);
    HeaderSymlinkTree thriftIncludeSymlinkTree =
        createFakeSymlinkTree(
            desc.createThriftIncludeSymlinkTreeTarget(unflavoredTarget), pathResolver, includeRoot);
    ThriftLibrary lib =
        new ThriftLibrary(
            unflavoredParams,
            pathResolver,
            ImmutableSortedSet.<ThriftLibrary>of(),
            thriftIncludeSymlinkTree,
            ImmutableMap.<Path, SourcePath>of());

    // Generate these rules using no deps.
    rules =
        desc.createThriftCompilerBuildRules(
            flavoredParams,
            resolver,
            ThriftLibraryDescription.CompilerType.THRIFT,
            ImmutableList.<String>of(),
            language,
            options,
            ImmutableMap.of(sourceName, sourcePath),
            ImmutableSortedSet.of(lib));

    // Now verify that the generated rule has all the deps from the passed in thrift library.
    assertSame(rules.size(), 1);
    rule = rules.get(sourceName);
    assertNotNull(rule);
    assertEquals(ImmutableSortedSet.<BuildRule>of(thriftIncludeSymlinkTree), rule.getDeps());

    // Setup a simple genrule that creates the thrift source and verify its dep is propagated.
    Genrule genrule =
        (Genrule)
            GenruleBuilder.newGenruleBuilder(BuildTargetFactory.newInstance("//:genrule"))
                .setOut(sourceName)
                .build(resolver);
    SourcePath ruleSourcePath = new BuildTargetSourcePath(genrule.getBuildTarget());

    // Generate these rules using no deps and the genrule generated source.
    rules =
        desc.createThriftCompilerBuildRules(
            flavoredParams,
            resolver,
            ThriftLibraryDescription.CompilerType.THRIFT,
            ImmutableList.<String>of(),
            language,
            options,
            ImmutableMap.of(sourceName, ruleSourcePath),
            ImmutableSortedSet.<ThriftLibrary>of());

    // Now verify that the generated rule had no associated deps.
    assertSame(rules.size(), 1);
    rule = rules.get(sourceName);
    assertNotNull(rule);
    assertEquals(ImmutableSortedSet.<BuildRule>of(genrule), rule.getDeps());

    // Create a build rule that represents the thrift rule.
    FakeBuildRule thriftRule = createFakeBuildRule("//thrift:target", pathResolver);
    resolver.addToIndex(thriftRule);
    filesystem.mkdirs(thriftRule.getBuildTarget().getBasePath());
    filesystem.touch(thriftRule.getBuildTarget().getBasePath().resolve("BUCK"));

    // Setup an empty thrift buck config, and set compiler target.
    buckConfig =
        new FakeBuckConfig(
            ImmutableMap.of(
                "thrift", ImmutableMap.of("compiler", thriftRule.getBuildTarget().toString())),
            filesystem);
    thriftBuckConfig = new ThriftBuckConfig(buckConfig);
    desc =
        new ThriftLibraryDescription(
            thriftBuckConfig, ImmutableList.<ThriftLanguageSpecificEnhancer>of());

    // Generate these rules using no deps with a compiler target.
    rules =
        desc.createThriftCompilerBuildRules(
            flavoredParams,
            resolver,
            ThriftLibraryDescription.CompilerType.THRIFT,
            ImmutableList.<String>of(),
            language,
            options,
            ImmutableMap.of(sourceName, sourcePath),
            ImmutableSortedSet.<ThriftLibrary>of());

    // Now verify that the generated rule only has deps from the compiler target.
    assertSame(rules.size(), 1);
    rule = rules.get(sourceName);
    assertNotNull(rule);
    assertEquals(ImmutableSortedSet.<BuildRule>of(thriftRule), rule.getDeps());
  }
  @Test
  public void createLexYaccBuildRules() throws IOException {
    BuildRuleResolver resolver = new BuildRuleResolver();

    // Setup our C++ buck config with the paths to the lex/yacc binaries.
    FakeProjectFilesystem filesystem = new FakeProjectFilesystem();
    Path lexPath = Paths.get("lex");
    filesystem.touch(lexPath);
    Path yaccPath = Paths.get("yacc");
    filesystem.touch(yaccPath);
    BuckConfig buckConfig =
        FakeBuckConfig.builder()
            .setSections(
                ImmutableMap.of(
                    "cxx",
                    ImmutableMap.of(
                        "lex", lexPath.toString(),
                        "yacc", yaccPath.toString())))
            .setFilesystem(filesystem)
            .build();
    CxxPlatform cxxBuckConfig = DefaultCxxPlatforms.build(new CxxBuckConfig(buckConfig));

    // Setup the target name and build params.
    UnflavoredBuildTarget target =
        BuildTargetFactory.newInstance("//:test").getUnflavoredBuildTarget();
    BuildRuleParams params = new FakeBuildRuleParamsBuilder(BuildTarget.of(target)).build();

    // Setup a genrule that generates our lex source.
    String lexSourceName = "test.ll";
    BuildTarget genruleTarget = BuildTargetFactory.newInstance("//:genrule_lex");
    Genrule genrule =
        (Genrule)
            GenruleBuilder.newGenruleBuilder(genruleTarget).setOut(lexSourceName).build(resolver);
    SourcePath lexSource = new BuildTargetSourcePath(genrule.getBuildTarget());

    // Use a regular path for our yacc source.
    String yaccSourceName = "test.yy";
    SourcePath yaccSource = new TestSourcePath(yaccSourceName);

    // Build the rules.
    CxxHeaderSourceSpec actual =
        CxxDescriptionEnhancer.createLexYaccBuildRules(
            params,
            resolver,
            cxxBuckConfig,
            ImmutableList.<String>of(),
            ImmutableMap.of(lexSourceName, lexSource),
            ImmutableList.<String>of(),
            ImmutableMap.of(yaccSourceName, yaccSource));

    // Grab the generated lex rule and verify it has the genrule as a dep.
    Lex lex =
        (Lex) resolver.getRule(CxxDescriptionEnhancer.createLexBuildTarget(target, lexSourceName));
    assertNotNull(lex);
    assertEquals(ImmutableSortedSet.<BuildRule>of(genrule), lex.getDeps());

    // Grab the generated yacc rule and verify it has no deps.
    Yacc yacc =
        (Yacc)
            resolver.getRule(CxxDescriptionEnhancer.createYaccBuildTarget(target, yaccSourceName));
    assertNotNull(yacc);
    assertEquals(ImmutableSortedSet.<BuildRule>of(), yacc.getDeps());

    // Check the header/source spec is correct.
    Path lexOutputSource = CxxDescriptionEnhancer.getLexSourceOutputPath(target, lexSourceName);
    Path lexOutputHeader = CxxDescriptionEnhancer.getLexHeaderOutputPath(target, lexSourceName);
    Path yaccOutputPrefix =
        CxxDescriptionEnhancer.getYaccOutputPrefix(
            target, Files.getNameWithoutExtension(yaccSourceName));
    Path yaccOutputSource = Yacc.getSourceOutputPath(yaccOutputPrefix);
    Path yaccOutputHeader = Yacc.getHeaderOutputPath(yaccOutputPrefix);
    CxxHeaderSourceSpec expected =
        CxxHeaderSourceSpec.of(
            ImmutableMap.<Path, SourcePath>of(
                target.getBasePath().resolve(lexSourceName + ".h"),
                new BuildTargetSourcePath(lex.getBuildTarget(), lexOutputHeader),
                target.getBasePath().resolve(yaccSourceName + ".h"),
                new BuildTargetSourcePath(yacc.getBuildTarget(), yaccOutputHeader)),
            ImmutableMap.of(
                lexSourceName + ".cc",
                CxxSource.of(
                    CxxSource.Type.CXX,
                    new BuildTargetSourcePath(lex.getBuildTarget(), lexOutputSource),
                    ImmutableList.<String>of()),
                yaccSourceName + ".cc",
                CxxSource.of(
                    CxxSource.Type.CXX,
                    new BuildTargetSourcePath(yacc.getBuildTarget(), yaccOutputSource),
                    ImmutableList.<String>of())));
    assertEquals(expected, actual);
  }
  @Test
  @SuppressWarnings("unchecked")
  public void testDependencies() throws Exception {
    TargetNode<?> hamcrestTargetNode =
        PrebuiltJarBuilder.createBuilder(
                BuildTargetFactory.newInstance("//third-party/hamcrest:hamcrest"))
            .setBinaryJar(Paths.get("third-party/hamcrest/hamcrest.jar"))
            .build();

    TargetNode<?> guavaTargetNode =
        PrebuiltJarBuilder.createBuilder(
                BuildTargetFactory.newInstance("//third-party/guava:guava"))
            .setBinaryJar(Paths.get("third-party/guava/guava.jar"))
            .build();

    TargetNode<?> baseTargetNode =
        JavaLibraryBuilder.createBuilder(
                BuildTargetFactory.newInstance("//java/com/example/base:base"))
            .addDep(guavaTargetNode.getBuildTarget())
            .addSrc(Paths.get("java/com/example/base/Base.java"))
            .build();

    TargetNode<?> baseGenruleTarget =
        GenruleBuilder.newGenruleBuilder(
                BuildTargetFactory.newInstance("//java/com/example/base:genrule"))
            .build();

    TargetNode<?> baseInlineTestsTargetNode =
        JavaLibraryBuilder.createBuilder(
                BuildTargetFactory.newInstance("//java/com/example/base:tests"))
            .addDep(hamcrestTargetNode.getBuildTarget())
            .addSrc(Paths.get("java/com/example/base/TestBase.java"))
            .addSrcTarget(baseGenruleTarget.getBuildTarget())
            .build();

    TargetNode<?> baseTestsTargetNode =
        JavaTestBuilder.createBuilder(
                BuildTargetFactory.newInstance("//javatests/com/example/base:base"))
            .addDep(baseTargetNode.getBuildTarget())
            .addDep(hamcrestTargetNode.getBuildTarget())
            .addSrc(Paths.get("javatests/com/example/base/Base.java"))
            .build();

    IjModuleGraph moduleGraph =
        IjModuleGraphTest.createModuleGraph(
            ImmutableSet.of(
                hamcrestTargetNode,
                guavaTargetNode,
                baseTargetNode,
                baseGenruleTarget,
                baseInlineTestsTargetNode,
                baseTestsTargetNode),
            ImmutableMap.<TargetNode<?>, Path>of(
                baseInlineTestsTargetNode, Paths.get("buck-out/baseInlineTests.jar")),
            Functions.constant(Optional.<Path>absent()));
    IjLibrary hamcrestLibrary =
        IjModuleGraphTest.getLibraryForTarget(moduleGraph, hamcrestTargetNode);
    IjLibrary guavaLibrary = IjModuleGraphTest.getLibraryForTarget(moduleGraph, guavaTargetNode);
    IjModule baseModule = IjModuleGraphTest.getModuleForTarget(moduleGraph, baseTargetNode);
    IjModule baseTestModule =
        IjModuleGraphTest.getModuleForTarget(moduleGraph, baseTestsTargetNode);

    IjProjectTemplateDataPreparer dataPreparer =
        new IjProjectTemplateDataPreparer(javaPackageFinder, moduleGraph, filesystem);

    assertEquals(
        IjModuleGraphTest.getModuleForTarget(moduleGraph, baseInlineTestsTargetNode),
        IjModuleGraphTest.getModuleForTarget(moduleGraph, baseTargetNode));

    DependencyEntryData.Builder dependencyEntryBuilder =
        DependencyEntryData.builder().setExported(false);

    assertThat(
        dataPreparer.getDependencies(baseModule),
        contains(
            allOf(
                hasProperty("type", equalTo(IjDependencyListBuilder.Type.LIBRARY)),
                hasProperty(
                    "data",
                    equalTo(
                        Optional.of(
                            dependencyEntryBuilder
                                .setName(guavaLibrary.getName())
                                .setScope(IjDependencyListBuilder.Scope.COMPILE)
                                .build())))),
            allOf(
                hasProperty("type", equalTo(IjDependencyListBuilder.Type.LIBRARY)),
                hasProperty(
                    "data",
                    equalTo(
                        Optional.of(
                            dependencyEntryBuilder
                                .setName(hamcrestLibrary.getName())
                                .setScope(IjDependencyListBuilder.Scope.COMPILE)
                                .build())))),
            allOf(hasProperty("type", equalTo(IjDependencyListBuilder.Type.SOURCE_FOLDER))),
            allOf(
                hasProperty("type", equalTo(IjDependencyListBuilder.Type.LIBRARY)),
                hasProperty(
                    "data",
                    equalTo(
                        Optional.of(
                            DependencyEntryData.builder()
                                .setExported(true)
                                .setName("library_java_com_example_base_tests")
                                .setScope(IjDependencyListBuilder.Scope.PROVIDED)
                                .build()))))));

    assertThat(
        dataPreparer.getDependencies(baseTestModule),
        contains(
            allOf(
                hasProperty("type", equalTo(IjDependencyListBuilder.Type.MODULE)),
                hasProperty(
                    "data",
                    equalTo(
                        Optional.of(
                            dependencyEntryBuilder
                                .setName(baseModule.getName())
                                .setScope(IjDependencyListBuilder.Scope.TEST)
                                .build())))),
            allOf(
                hasProperty("type", equalTo(IjDependencyListBuilder.Type.LIBRARY)),
                hasProperty(
                    "data",
                    equalTo(
                        Optional.of(
                            dependencyEntryBuilder
                                .setName(hamcrestLibrary.getName())
                                .setScope(IjDependencyListBuilder.Scope.TEST)
                                .build())))),
            allOf(hasProperty("type", equalTo(IjDependencyListBuilder.Type.SOURCE_FOLDER)))));
  }