@Test public void stringifiedRuleKeyAppendablesGetAddedToRuleKeyAsStrings() { BuildTarget target = BuildTargetFactory.newInstance("//cheese:peas"); SourcePathResolver pathResolver = new SourcePathResolver(new BuildRuleResolver()); BuildRule rule = new EmptyRule(target); DefaultRuleKeyBuilderFactory factory = new DefaultRuleKeyBuilderFactory(new NullFileHashCache(), pathResolver); RuleKeyBuilder builder = factory.newInstance(rule); builder.setReflectively("field", "cheddar"); RuleKey expected = builder.build(); class AppendingField extends EmptyRule { @AddToRuleKey(stringify = true) private Appender field = new Appender(); public AppendingField(BuildTarget target) { super(target); } } RuleKey seen = factory.build(new AppendingField(target)); assertEquals(expected, seen); }
@Test public void shouldAddASingleAnnotatedFieldToRuleKey() { BuildTarget target = BuildTargetFactory.newInstance("//cheese:peas"); SourcePathResolver pathResolver = new SourcePathResolver(new BuildRuleResolver()); BuildRule rule = new EmptyRule(target); DefaultRuleKeyBuilderFactory factory = new DefaultRuleKeyBuilderFactory(new NullFileHashCache(), pathResolver); RuleKeyBuilder builder = factory.newInstance(rule); builder.setReflectively("field", "cake-walk"); RuleKey expected = builder.build(); class DecoratedFields extends EmptyRule { @AddToRuleKey private String field = "cake-walk"; public DecoratedFields(BuildTarget target) { super(target); } } RuleKey seen = factory.build(new DecoratedFields(target)); assertEquals(expected, seen); }
@Test public void fieldsFromParentClassesAreAlsoAdded() { BuildTarget target = BuildTargetFactory.newInstance("//cheese:peas"); SourcePathResolver pathResolver = new SourcePathResolver(new BuildRuleResolver()); BuildRule rule = new EmptyRule(target); DefaultRuleKeyBuilderFactory factory = new DefaultRuleKeyBuilderFactory(new NullFileHashCache(), pathResolver); RuleKeyBuilder builder = factory.newInstance(rule); builder.setReflectively("key", "child"); builder.setReflectively("key", "parent"); RuleKey expected = builder.build(); class Parent extends EmptyRule { @AddToRuleKey private String key = "parent"; public Parent(BuildTarget target) { super(target); } } class Child extends Parent { @AddToRuleKey private String key = "child"; public Child(BuildTarget target) { super(target); } } RuleKey seen = factory.build(new Child(target)); assertEquals(expected, seen); }
@Test public void fieldsAreAddedInAlphabeticalOrder() { BuildTarget target = BuildTargetFactory.newInstance("//cheese:peas"); SourcePathResolver pathResolver = new SourcePathResolver(new BuildRuleResolver()); BuildRule rule = new EmptyRule(target); DefaultRuleKeyBuilderFactory factory = new DefaultRuleKeyBuilderFactory(new NullFileHashCache(), pathResolver); RuleKeyBuilder builder = factory.newInstance(rule); builder.setReflectively("alpha", "stilton"); builder.setReflectively("beta", 1); builder.setReflectively("gamma", "stinking bishop"); RuleKey expected = builder.build(); class UnsortedFields extends EmptyRule { @AddToRuleKey private String gamma = "stinking bishop"; @AddToRuleKey private int beta = 1; @AddToRuleKey private String alpha = "stilton"; public UnsortedFields(BuildTarget target) { super(target); } } RuleKey seen = factory.build(new UnsortedFields(target)); assertEquals(expected, seen); }
@Test public void shouldAllowRuleKeyAppendablesToAppendToRuleKey() { BuildTarget target = BuildTargetFactory.newInstance("//cheese:peas"); SourcePathResolver pathResolver = new SourcePathResolver(new BuildRuleResolver()); BuildRule rule = new EmptyRule(target); FileHashCache fileHashCache = new NullFileHashCache(); DefaultRuleKeyBuilderFactory factory = new DefaultRuleKeyBuilderFactory(fileHashCache, pathResolver); RuleKey subKey = new RuleKeyBuilder(pathResolver, fileHashCache).setReflectively("cheese", "brie").build(); RuleKeyBuilder builder = factory.newInstance(rule); builder.setReflectively("field.appendableSubKey", subKey); RuleKey expected = builder.build(); class AppendingField extends EmptyRule { @AddToRuleKey private Appender field = new Appender(); public AppendingField(BuildTarget target) { super(target); } } RuleKey seen = factory.build(new AppendingField(target)); assertEquals(expected, seen); }
@Test public void shouldAllowAFieldToBeStringified() { BuildTarget target = BuildTargetFactory.newInstance("//cheese:peas"); SourcePathResolver pathResolver = new SourcePathResolver(new BuildRuleResolver()); BuildRule rule = new EmptyRule(target); DefaultRuleKeyBuilderFactory factory = new DefaultRuleKeyBuilderFactory(new NullFileHashCache(), pathResolver); RuleKeyBuilder builder = factory.newInstance(rule); builder.setReflectively("field", "sausages"); RuleKey expected = builder.build(); class Stringifiable { @Override public String toString() { return "sausages"; } } class StringifiedField extends EmptyRule { @AddToRuleKey(stringify = true) private Stringifiable field = new Stringifiable(); public StringifiedField(BuildTarget target) { super(target); } } RuleKey seen = factory.build(new StringifiedField(target)); assertEquals(expected, seen); }
@Override public RuleKeyBuilder appendToRuleKey(RuleKeyBuilder builder) { builder.setReflectively("cCompiler", cCompiler); builder.setReflectively("ocamlCompiler", ocamlCompiler); // TODO(user): Ensure that this is not an absolute path. builder.setReflectively("output", output.toString()); builder.setReflectively("input", input); builder.setReflectively("flags", flags); builder.setReflectively("includes", includes); return builder; }
@Test public void annotatedAppendableBuildRulesIncludeTheirRuleKey() { BuildTarget target = BuildTargetFactory.newInstance("//cheese:peas"); BuildTarget depTarget = BuildTargetFactory.newInstance("//cheese:more-peas"); SourcePathResolver pathResolver = new SourcePathResolver(new BuildRuleResolver()); BuildRule rule = new EmptyRule(target); FileHashCache fileHashCache = new NullFileHashCache(); DefaultRuleKeyBuilderFactory factory = new DefaultRuleKeyBuilderFactory(fileHashCache, pathResolver); class AppendableRule extends EmptyRule implements RuleKeyAppendable { public AppendableRule(BuildTarget target) { super(target); } @Override public RuleKeyBuilder appendToRuleKey(RuleKeyBuilder builder) { return builder.setReflectively("cheese", "brie"); } @Override public RuleKey getRuleKey() { return new RuleKey("abcd"); } } AppendableRule appendableRule = new AppendableRule(depTarget); RuleKey subKey = new RuleKeyBuilder(pathResolver, fileHashCache).setReflectively("cheese", "brie").build(); RuleKeyBuilder builder = factory.newInstance(rule); builder.setReflectively("field.appendableSubKey", subKey); builder.setReflectively("field", appendableRule.getRuleKey()); RuleKey expected = builder.build(); class RuleContainingAppendableRule extends EmptyRule { @AddToRuleKey private final AppendableRule field; public RuleContainingAppendableRule(BuildTarget target, AppendableRule appendableRule) { super(target); this.field = appendableRule; } } RuleKey seen = factory.build(new RuleContainingAppendableRule(target, appendableRule)); assertEquals(expected, seen); }
@Override public RuleKeyBuilder appendToRuleKey(RuleKeyBuilder builder) { // Build a sorted set so that metaInfDirectory contents are listed in a canonical order. ImmutableSortedSet.Builder<Path> paths = ImmutableSortedSet.naturalOrder(); BuildRules.addInputsToSortedSet(metaInfDirectory, paths, directoryTraverser); return builder.setReflectively("metaInfDirectory", paths.build()); }
@Override public RuleKeyBuilder appendToRuleKey(RuleKeyBuilder builder) { try { return builder .setReflectively("arg", unexpanded) .setReflectively( "macros", expander.extractRuleKeyAppendables(target, cellNames, resolver, unexpanded)); } catch (MacroException e) { throw new HumanReadableException(e, "%s: %s", target, e.getMessage()); } }
@Test public void shouldUpdateRuleKey() throws Exception { @SuppressWarnings("unchecked") RuleKeyBuilder<RuleKey> ruleKeyBuilder = createMock(RuleKeyBuilder.class); expect(ruleKeyBuilder.setReflectively("minSdkVersion", Optional.of(5))) .andReturn(ruleKeyBuilder); expect(ruleKeyBuilder.setReflectively("targetSdkVersion", Optional.of(7))) .andReturn(ruleKeyBuilder); expect(ruleKeyBuilder.setReflectively("versionCode", Optional.of(11))) .andReturn(ruleKeyBuilder); expect(ruleKeyBuilder.setReflectively("versionName", Optional.of("thirteen"))) .andReturn(ruleKeyBuilder); expect(ruleKeyBuilder.setReflectively("debugMode", Optional.absent())) .andReturn(ruleKeyBuilder); replay(ruleKeyBuilder); ManifestEntries entries = ManifestEntries.builder() .setMinSdkVersion(5) .setTargetSdkVersion(7) .setVersionCode(11) .setVersionName("thirteen") .build(); // The appendToRuleKey should set both present and absent properties entries.appendToRuleKey(ruleKeyBuilder); }
@Test public void fieldsFromParentClassesShouldBeAddedAndFieldsRetainOverallAlphabeticalOrdering() { BuildTarget topLevelTarget = BuildTargetFactory.newInstance("//cheese:peas"); SourcePathResolver pathResolver = new SourcePathResolver(new BuildRuleResolver()); BuildRule rule = new EmptyRule(topLevelTarget); DefaultRuleKeyBuilderFactory factory = new DefaultRuleKeyBuilderFactory(new NullFileHashCache(), pathResolver); RuleKeyBuilder builder = factory.newInstance(rule); builder.setReflectively("exoticCheese", "bavarian smoked"); builder.setReflectively("target", topLevelTarget.getFullyQualifiedName()); RuleKey expected = builder.build(); class Parent extends EmptyRule { @AddToRuleKey private BuildTarget target; public Parent(BuildTarget target) { super(target); this.target = target; } } class Child extends Parent { @AddToRuleKey private String exoticCheese = "bavarian smoked"; public Child(BuildTarget target) { super(target); } } RuleKey seen = factory.build(new Child(topLevelTarget)); assertEquals(expected, seen); }
@Override public RuleKeyBuilder appendToRuleKey(RuleKeyBuilder builder) { // Hash in the pre-filtered native libraries we're pulling in. ImmutableSortedMap<Pair<TargetCpuType, String>, SourcePath> sortedLibs = ImmutableSortedMap.<Pair<TargetCpuType, String>, SourcePath>orderedBy( Pair.<TargetCpuType, String>comparator()) .putAll(filteredNativeLibraries) .build(); for (Map.Entry<Pair<TargetCpuType, String>, SourcePath> entry : sortedLibs.entrySet()) { Pair<TargetCpuType, String> entryKey = entry.getKey(); builder.setReflectively( String.format("lib(%s, %s)", entryKey.getFirst(), entryKey.getSecond()), entry.getValue()); } return builder; }
@Override public RuleKeyBuilder appendToRuleKey(RuleKeyBuilder builder) { return builder.setReflectively("filter", getDescription()); }
@Override public RuleKeyBuilder appendToRuleKey(RuleKeyBuilder builder) { return builder.setReflectively("cheese", "brie"); }