@Test public void fieldsWithIsDepEqualsFalseHintAreNotTreatedAsDeps() throws ConstructorArgMarshalException, NoSuchBuildTargetException { class Dto { @Hint(isDep = false) public Optional<Set<BuildTarget>> deps; } final String dep = "//should/be:ignored"; Dto dto = new Dto(); Map<String, Object> args = Maps.newHashMap(); args.put("deps", ImmutableList.of(dep)); ImmutableSet.Builder<BuildTarget> declaredDeps = ImmutableSet.builder(); marshaller.populate( createCellRoots(filesystem), filesystem, buildRuleFactoryParams(), dto, declaredDeps, ImmutableSet.<BuildTargetPattern>builder(), args); assertEquals(ImmutableSet.of(), declaredDeps.build()); }
public void shouldSetBuildTargetParameters() throws ConstructorArgMarshalException, NoSuchBuildTargetException { class Dto { public BuildTarget single; public BuildTarget sameBuildFileTarget; public List<BuildTarget> targets; } Dto dto = new Dto(); marshaller.populate( createCellRoots(filesystem), filesystem, buildRuleFactoryParams(), dto, ImmutableSet.<BuildTarget>builder(), ImmutableSet.<BuildTargetPattern>builder(), ImmutableMap.<String, Object>of( "single", "//com/example:cheese", "sameBuildFileTarget", ":cake", "targets", ImmutableList.of(":cake", "//com/example:cheese"))); BuildTarget cheese = BuildTargetFactory.newInstance("//com/example:cheese"); BuildTarget cake = BuildTargetFactory.newInstance("//example/path:cake"); assertEquals(cheese, dto.single); assertEquals(cake, dto.sameBuildFileTarget); assertEquals(ImmutableList.of(cake, cheese), dto.targets); }
@Test public void shouldPopulateSourcePaths() throws ConstructorArgMarshalException, NoSuchBuildTargetException { class Dto { public SourcePath filePath; public SourcePath targetPath; } ProjectFilesystem projectFilesystem = new FakeProjectFilesystem(); BuildTarget target = BuildTargetFactory.newInstance("//example/path:peas"); FakeBuildRule rule = new FakeBuildRule(target, new SourcePathResolver(new BuildRuleResolver())); ruleResolver.addToIndex(rule); Dto dto = new Dto(); marshaller.populate( createCellRoots(filesystem), filesystem, buildRuleFactoryParams(), dto, ImmutableSet.<BuildTarget>builder(), ImmutableSet.<BuildTargetPattern>builder(), ImmutableMap.<String, Object>of( "filePath", "cheese.txt", "targetPath", ":peas")); assertEquals( new PathSourcePath(projectFilesystem, Paths.get("example/path/cheese.txt")), dto.filePath); assertEquals(new BuildTargetSourcePath(rule.getBuildTarget()), dto.targetPath); }
@Test public void upperBoundGenericTypesCauseValuesToBeSetToTheUpperBound() throws ConstructorArgMarshalException, NoSuchBuildTargetException { class Dto { public List<? extends SourcePath> yup; } ProjectFilesystem projectFilesystem = new FakeProjectFilesystem(); SourcePathResolver pathResolver = new SourcePathResolver(new BuildRuleResolver()); BuildRule rule = new FakeBuildRule(BuildTargetFactory.newInstance("//will:happen"), pathResolver); ruleResolver.addToIndex(rule); Dto dto = new Dto(); marshaller.populate( createCellRoots(filesystem), filesystem, buildRuleFactoryParams(), dto, ImmutableSet.<BuildTarget>builder(), ImmutableSet.<BuildTargetPattern>builder(), ImmutableMap.<String, Object>of( "yup", ImmutableList.of(rule.getBuildTarget().getFullyQualifiedName()))); BuildTargetSourcePath path = new BuildTargetSourcePath(rule.getBuildTarget()); assertEquals(ImmutableList.of(path), dto.yup); }
@Test public void onlyFieldNamedDepsAreConsideredDeclaredDeps() throws ConstructorArgMarshalException, NoSuchBuildTargetException { class Dto { public Optional<Set<BuildTarget>> deps; public Optional<Set<BuildTarget>> notdeps; } final String dep = "//is/a/declared:dep"; final String notDep = "//is/not/a/declared:dep"; BuildTarget declaredDep = BuildTargetFactory.newInstance(dep); Dto dto = new Dto(); Map<String, Object> args = Maps.newHashMap(); args.put("deps", ImmutableList.of(dep)); args.put("notdeps", ImmutableList.of(notDep)); ImmutableSet.Builder<BuildTarget> declaredDeps = ImmutableSet.builder(); marshaller.populate( createCellRoots(filesystem), filesystem, buildRuleFactoryParams(), dto, declaredDeps, ImmutableSet.<BuildTargetPattern>builder(), args); assertEquals(ImmutableSet.of(declaredDep), declaredDeps.build()); }
@Test(expected = RuntimeException.class) public void lowerBoundGenericTypesCauseAnException() throws ConstructorArgMarshalException, NoSuchBuildTargetException { class Dto { public List<? super BuildTarget> nope; } marshaller.populate( createCellRoots(filesystem), filesystem, buildRuleFactoryParams(), new Dto(), ImmutableSet.<BuildTarget>builder(), ImmutableSet.<BuildTargetPattern>builder(), ImmutableMap.<String, Object>of("nope", ImmutableList.of("//will/not:happen"))); }
@Test public void testImplicitDepsAreAddedCorrectly() throws NoSuchBuildTargetException { Description<GenruleDescription.Arg> genruleDescription = new GenruleDescription(); Map<String, Object> instance = ImmutableMap.<String, Object>of( "srcs", ImmutableList.of(":baz", "//biz:baz"), "out", "AndroidManifest.xml", "cmd", "$(exe //bin:executable) $(location :arg)"); ProjectFilesystem projectFilesystem = new AllExistingProjectFilesystem(); BuildRuleFactoryParams params = new BuildRuleFactoryParams(projectFilesystem, BuildTargetFactory.newInstance("//foo:bar")); ConstructorArgMarshaller marshaller = new ConstructorArgMarshaller( new DefaultTypeCoercerFactory(ObjectMappers.newDefaultInstance())); ImmutableSet.Builder<BuildTarget> declaredDeps = ImmutableSet.builder(); ImmutableSet.Builder<VisibilityPattern> visibilityPatterns = ImmutableSet.builder(); GenruleDescription.Arg constructorArg = genruleDescription.createUnpopulatedConstructorArg(); try { marshaller.populate( createCellRoots(projectFilesystem), projectFilesystem, params, constructorArg, declaredDeps, visibilityPatterns, instance); } catch (ConstructorArgMarshalException e) { fail("Expected constructorArg to be correctly populated."); } TargetNode<GenruleDescription.Arg> targetNode = new TargetNodeFactory(new DefaultTypeCoercerFactory(ObjectMappers.newDefaultInstance())) .create( Hashing.sha1().hashString(params.target.getFullyQualifiedName(), UTF_8), genruleDescription, constructorArg, params, declaredDeps.build(), visibilityPatterns.build(), createCellRoots(projectFilesystem)); assertEquals( "SourcePaths and targets from cmd string should be extracted as extra deps.", ImmutableSet.of("//foo:baz", "//biz:baz", "//bin:executable", "//foo:arg"), FluentIterable.from(targetNode.getExtraDeps()) .transform(Functions.toStringFunction()) .toSet()); }
@Test public void shouldNotPopulateAnEmptyArg() throws NoSuchBuildTargetException { class Dto {} Dto dto = new Dto(); try { marshaller.populate( createCellRoots(filesystem), filesystem, buildRuleFactoryParams(), dto, ImmutableSet.<BuildTarget>builder(), ImmutableSet.<BuildTargetPattern>builder(), ImmutableMap.<String, Object>of()); } catch (RuntimeException | ConstructorArgMarshalException e) { fail("Did not expect an exception to be thrown:\n" + Throwables.getStackTraceAsString(e)); } }
@Test(expected = ConstructorArgMarshalException.class) public void shouldBeAnErrorToAttemptToSetACollectionToASingleValue() throws ConstructorArgMarshalException, NoSuchBuildTargetException { class Dto { public Set<String> strings; } Dto dto = new Dto(); marshaller.populate( createCellRoots(filesystem), filesystem, buildRuleFactoryParams(), dto, ImmutableSet.<BuildTarget>builder(), ImmutableSet.<BuildTargetPattern>builder(), ImmutableMap.<String, Object>of("strings", "isn't going to happen")); }
@Test(expected = ConstructorArgMarshalException.class) public void shouldBeAnErrorToSetTheWrongTypeOfValueInACollection() throws ConstructorArgMarshalException, NoSuchBuildTargetException { class Dto { public Set<String> strings; } Dto dto = new Dto(); marshaller.populate( createCellRoots(filesystem), filesystem, buildRuleFactoryParams(), dto, ImmutableSet.<BuildTarget>builder(), ImmutableSet.<BuildTargetPattern>builder(), ImmutableMap.<String, Object>of("strings", ImmutableSet.of(true, false))); }
@Test public void shouldPopulateABooleanValue() throws ConstructorArgMarshalException, NoSuchBuildTargetException { class Dto { public boolean value; } Dto dto = new Dto(); marshaller.populate( createCellRoots(filesystem), filesystem, buildRuleFactoryParams(), dto, ImmutableSet.<BuildTarget>builder(), ImmutableSet.<BuildTargetPattern>builder(), ImmutableMap.<String, Object>of("value", true)); assertTrue(dto.value); }
@Test public void shouldPopulateANumericValue() throws ConstructorArgMarshalException, NoSuchBuildTargetException { class Dto { public long number; } Dto dto = new Dto(); marshaller.populate( createCellRoots(filesystem), filesystem, buildRuleFactoryParams(), dto, ImmutableSet.<BuildTarget>builder(), ImmutableSet.<BuildTargetPattern>builder(), ImmutableMap.<String, Object>of("number", 42L)); assertEquals(42, dto.number); }
/** * Use the information contained in the {@code params} to fill in the public fields and settable * properties of {@code dto}. The following rules are used: * * <ul> * <li>Boolean values are set to true or false. * <li>{@link BuildTarget}s are resolved and will be fully qualified. * <li>Numeric values are handled as if being cast from Long. * <li>{@link SourcePath} instances will be set to the appropriate implementation. * <li>{@link Path} declarations will be set to be relative to the project root. * <li>Strings will be set "as is". * <li>{@link List}s and {@link Set}s will be populated with the expected generic type, provided * the wildcarding allows an upperbound to be determined to be one of the above. * </ul> * * Any property that is marked as being an {@link Optional} field will be set to a default value * if none is set. This is typically {@link Optional#absent()}, but in the case of collections is * an empty collection. * * @param params The parameters to be used to populate the {@code dto} instance. * @param dto The constructor dto to be populated. * @param declaredDeps A builder to be populated with the declared dependencies. * @param visibilityPatterns A builder to be populated with the visibility patterns. */ public void populate( Function<Optional<String>, Path> cellRoots, ProjectFilesystem filesystem, BuildRuleFactoryParams params, Object dto, ImmutableSet.Builder<BuildTarget> declaredDeps, ImmutableSet.Builder<BuildTargetPattern> visibilityPatterns, Map<String, ?> instance) throws ConstructorArgMarshalException, NoSuchBuildTargetException { populate( cellRoots, filesystem, params, dto, declaredDeps, instance, /* populate all fields, optional and required */ false); populateVisibilityPatterns(cellRoots, visibilityPatterns, instance); }
@Test public void shouldPopulateAStringValue() throws ConstructorArgMarshalException, NoSuchBuildTargetException { class Dto { public String name; } Dto dto = new Dto(); marshaller.populate( createCellRoots(filesystem), filesystem, buildRuleFactoryParams(), dto, ImmutableSet.<BuildTarget>builder(), ImmutableSet.<BuildTargetPattern>builder(), ImmutableMap.<String, Object>of("name", "cheese")); assertEquals("cheese", dto.name); }
@Test public void shouldPopulateLists() throws ConstructorArgMarshalException, NoSuchBuildTargetException { class Dto { public List<String> list; } Dto dto = new Dto(); marshaller.populate( createCellRoots(filesystem), filesystem, buildRuleFactoryParams(), dto, ImmutableSet.<BuildTarget>builder(), ImmutableSet.<BuildTargetPattern>builder(), ImmutableMap.<String, Object>of("list", ImmutableList.of("alpha", "beta"))); assertEquals(ImmutableList.of("alpha", "beta"), dto.list); }
@Test /** * Since we populated the params from the python script, and the python script inserts default * values instead of nulls it's never possible for someone to see "Optional.absent()", but that's * what we want as authors of buildables. Handle that case. */ public void shouldPopulateDefaultValuesAsBeingAbsent() throws ConstructorArgMarshalException, NoSuchBuildTargetException { class Dto { public Optional<String> noString; public Optional<String> defaultString; public Optional<SourcePath> noSourcePath; public Optional<SourcePath> defaultSourcePath; public int primitiveNum; public Integer wrapperObjectNum; public boolean primitiveBoolean; public Boolean wrapperObjectBoolean; } // This is not an ImmutableMap so we can test null values. Map<String, Object> args = Maps.newHashMap(); args.put("defaultString", null); args.put("defaultSourcePath", null); Dto dto = new Dto(); marshaller.populate( createCellRoots(filesystem), filesystem, buildRuleFactoryParams(), dto, ImmutableSet.<BuildTarget>builder(), ImmutableSet.<BuildTargetPattern>builder(), args); assertEquals(Optional.<String>absent(), dto.noString); assertEquals(Optional.<String>absent(), dto.defaultString); assertEquals(Optional.<SourcePath>absent(), dto.noSourcePath); assertEquals(Optional.<SourcePath>absent(), dto.defaultSourcePath); assertEquals(0, dto.primitiveNum); assertEquals(Integer.valueOf(0), dto.wrapperObjectNum); }
@Test public void specifyingZeroIsNotConsideredOptional() throws ConstructorArgMarshalException, NoSuchBuildTargetException { class Dto { public Optional<Integer> number; } Dto dto = new Dto(); marshaller.populate( createCellRoots(filesystem), filesystem, buildRuleFactoryParams(), dto, ImmutableSet.<BuildTarget>builder(), ImmutableSet.<BuildTargetPattern>builder(), ImmutableMap.<String, Object>of("number", 0)); assertTrue(dto.number.isPresent()); assertEquals(Optional.of(0), dto.number); }
@Test public void shouldPopulateAPathValue() throws ConstructorArgMarshalException, NoSuchBuildTargetException { class Dto { @Hint(name = "some_path") public Path somePath; } Dto dto = new Dto(); marshaller.populate( createCellRoots(filesystem), filesystem, buildRuleFactoryParams(), dto, ImmutableSet.<BuildTarget>builder(), ImmutableSet.<BuildTargetPattern>builder(), ImmutableMap.<String, Object>of("somePath", "Fish.java")); assertEquals(Paths.get("example/path", "Fish.java"), dto.somePath); }
@Test public void shouldNormalizePaths() throws ConstructorArgMarshalException, NoSuchBuildTargetException { class Dto { public Path path; } Dto dto = new Dto(); marshaller.populate( createCellRoots(filesystem), filesystem, buildRuleFactoryParams(), dto, ImmutableSet.<BuildTarget>builder(), ImmutableSet.<BuildTargetPattern>builder(), ImmutableMap.<String, Object>of("path", "./bar/././fish.txt")); assertEquals(basePath.resolve("bar/fish.txt").normalize(), dto.path); }
@Test public void shouldPopulateSets() throws ConstructorArgMarshalException, NoSuchBuildTargetException { class Dto { public Set<Path> paths; } Dto dto = new Dto(); marshaller.populate( createCellRoots(filesystem), filesystem, buildRuleFactoryParams(), dto, ImmutableSet.<BuildTarget>builder(), ImmutableSet.<BuildTargetPattern>builder(), ImmutableMap.<String, Object>of("paths", ImmutableList.of("one", "two"))); assertEquals( ImmutableSet.of(Paths.get("example/path/one"), Paths.get("example/path/two")), dto.paths); }
@Test public void shouldResolveCollectionOfSourcePaths() throws ConstructorArgMarshalException, NoSuchBuildTargetException { class Dto { public ImmutableSortedSet<SourcePath> srcs; } BuildRuleResolver resolver = new BuildRuleResolver(); BuildTarget target = BuildTargetFactory.newInstance("//example/path:manifest"); BuildRule rule = new FakeBuildRule(target, new SourcePathResolver(resolver)); resolver.addToIndex(rule); Dto dto = new Dto(); marshaller.populate( createCellRoots(filesystem), filesystem, buildRuleFactoryParams(), dto, ImmutableSet.<BuildTarget>builder(), ImmutableSet.<BuildTargetPattern>builder(), ImmutableMap.<String, Object>of( "srcs", ImmutableList.of("main.py", "lib/__init__.py", "lib/manifest.py"))); ImmutableSet<String> observedValues = FluentIterable.from(dto.srcs) .transform( new Function<SourcePath, String>() { @Nullable @Override public String apply(SourcePath input) { return ((PathSourcePath) input).getRelativePath().toString(); } }) .toSet(); assertEquals( ImmutableSet.of( Paths.get("example/path/main.py").toString(), Paths.get("example/path/lib/__init__.py").toString(), Paths.get("example/path/lib/manifest.py").toString()), observedValues); }
@Test public void testImplicitDepsAreAddedCorrectly() throws NoSuchBuildTargetException, TargetNode.InvalidSourcePathInputException { Description<GenruleDescription.Arg> genruleDescription = new GenruleDescription(); Map<String, Object> instance = ImmutableMap.<String, Object>of( "srcs", ImmutableList.of(":baz", "//biz:baz"), "out", "AndroidManifest.xml", "cmd", "$(exe //bin:executable) $(location :arg)"); ProjectFilesystem projectFilesystem = new AllExistingProjectFilesystem(); BuildRuleFactoryParams params = new BuildRuleFactoryParams( projectFilesystem, BuildTargetFactory.newInstance("//foo:bar"), new InMemoryBuildFileTree(ImmutableList.<BuildTarget>of()), /* enforeBuckBoundaryCheck */ true); ConstructorArgMarshaller marshaller = new ConstructorArgMarshaller(); ImmutableSet.Builder<BuildTarget> declaredDeps = ImmutableSet.builder(); ImmutableSet.Builder<BuildTargetPattern> visibilityPatterns = ImmutableSet.builder(); GenruleDescription.Arg constructorArg = genruleDescription.createUnpopulatedConstructorArg(); try { marshaller.populate( projectFilesystem, params, constructorArg, declaredDeps, visibilityPatterns, instance); } catch (ConstructorArgMarshalException e) { fail("Expected constructorArg to be correctly populated."); } TargetNode<GenruleDescription.Arg> targetNode = new TargetNode<>( genruleDescription, constructorArg, params, declaredDeps.build(), visibilityPatterns.build()); assertEquals( "SourcePaths and targets from cmd string should be extracted as extra deps.", ImmutableSet.of("//foo:baz", "//biz:baz", "//bin:executable", "//foo:arg"), FluentIterable.from(targetNode.getExtraDeps()) .transform(Functions.toStringFunction()) .toSet()); }
@Test public void shouldPopulateBuildTargetValues() throws ConstructorArgMarshalException, NoSuchBuildTargetException { class Dto { public BuildTarget target; public BuildTarget local; } Dto dto = new Dto(); marshaller.populate( createCellRoots(filesystem), filesystem, buildRuleFactoryParams(), dto, ImmutableSet.<BuildTarget>builder(), ImmutableSet.<BuildTargetPattern>builder(), ImmutableMap.<String, Object>of( "target", "//cake:walk", "local", ":fish")); assertEquals(BuildTargetFactory.newInstance(filesystem, "//cake:walk"), dto.target); assertEquals(BuildTargetFactory.newInstance(filesystem, "//example/path:fish"), dto.local); }
@Test public void shouldPopulateAnImmutableSortedSet() throws ConstructorArgMarshalException, NoSuchBuildTargetException { class Dto { public ImmutableSortedSet<BuildTarget> deps; } BuildTarget t1 = BuildTargetFactory.newInstance("//please/go:here"); BuildTarget t2 = BuildTargetFactory.newInstance("//example/path:there"); Dto dto = new Dto(); // Note: the ordering is reversed from the natural ordering marshaller.populate( createCellRoots(filesystem), filesystem, buildRuleFactoryParams(), dto, ImmutableSet.<BuildTarget>builder(), ImmutableSet.<BuildTargetPattern>builder(), ImmutableMap.<String, Object>of("deps", ImmutableList.of("//please/go:here", ":there"))); assertEquals(ImmutableSortedSet.of(t2, t1), dto.deps); }
@Test public void collectionsCanBeOptionalAndWillBeSetToAnOptionalEmptyCollectionIfMissing() throws ConstructorArgMarshalException, NoSuchBuildTargetException { class Dto { public Optional<Set<BuildTarget>> targets; } Dto dto = new Dto(); Map<String, Object> args = Maps.newHashMap(); args.put("targets", Lists.newArrayList()); marshaller.populate( createCellRoots(filesystem), filesystem, buildRuleFactoryParams(), dto, ImmutableSet.<BuildTarget>builder(), ImmutableSet.<BuildTargetPattern>builder(), args); assertEquals(Optional.of((Set<BuildTarget>) Sets.<BuildTarget>newHashSet()), dto.targets); }
@Test public void optionalCollectionsWithoutAValueWillBeSetToAnEmptyOptionalCollection() throws ConstructorArgMarshalException, NoSuchBuildTargetException { class Dto { public Optional<Set<String>> strings; } Dto dto = new Dto(); Map<String, Object> args = Maps.newHashMap(); // Deliberately not populating args marshaller.populate( createCellRoots(filesystem), filesystem, buildRuleFactoryParams(), dto, ImmutableSet.<BuildTarget>builder(), ImmutableSet.<BuildTargetPattern>builder(), args); assertEquals(Optional.of((Set<String>) Sets.<String>newHashSet()), dto.strings); }
@SuppressWarnings({"rawtypes", "unchecked"}) private TargetNode<?> createTargetNode( BuckEventBus eventBus, Cell cell, Path buildFile, BuildTarget target, Map<String, Object> rawNode, TargetNodeListener nodeListener) { BuildRuleType buildRuleType = parseBuildRuleTypeFromRawRule(cell, rawNode); // Because of the way that the parser works, we know this can never return null. Description<?> description = cell.getDescription(buildRuleType); if (target.isFlavored()) { if (description instanceof Flavored) { if (!((Flavored) description).hasFlavors(ImmutableSet.copyOf(target.getFlavors()))) { throw new HumanReadableException( "Unrecognized flavor in target %s while parsing %s%s.", target, UnflavoredBuildTarget.BUILD_TARGET_PREFIX, MorePaths.pathWithUnixSeparators( target.getBasePath().resolve(cell.getBuildFileName()))); } } else { LOG.warn( "Target %s (type %s) must implement the Flavored interface " + "before we can check if it supports flavors: %s", target.getUnflavoredBuildTarget(), buildRuleType, target.getFlavors()); throw new HumanReadableException( "Target %s (type %s) does not currently support flavors (tried %s)", target.getUnflavoredBuildTarget(), buildRuleType, target.getFlavors()); } } Cell targetCell = cell.getCell(target); BuildRuleFactoryParams factoryParams = new BuildRuleFactoryParams( targetCell.getFilesystem(), target.withoutCell(), new FilesystemBackedBuildFileTree(cell.getFilesystem(), cell.getBuildFileName()), targetCell.isEnforcingBuckPackageBoundaries()); Object constructorArg = description.createUnpopulatedConstructorArg(); try { ImmutableSet.Builder<BuildTarget> declaredDeps = ImmutableSet.builder(); ImmutableSet.Builder<BuildTargetPattern> visibilityPatterns = ImmutableSet.builder(); try (SimplePerfEvent.Scope scope = SimplePerfEvent.scope( eventBus, PerfEventId.of("MarshalledConstructorArg"), "target", target)) { marshaller.populate( targetCell.getCellRoots(), targetCell.getFilesystem(), factoryParams, constructorArg, declaredDeps, visibilityPatterns, rawNode); } try (SimplePerfEvent.Scope scope = SimplePerfEvent.scope(eventBus, PerfEventId.of("CreatedTargetNode"), "target", target)) { Hasher hasher = Hashing.sha1().newHasher(); hasher.putString(BuckVersion.getVersion(), UTF_8); JsonObjectHashing.hashJsonObject(hasher, rawNode); synchronized (this) { targetsCornucopia.put(target.getUnflavoredBuildTarget(), target); } TargetNode<?> node = new TargetNode( hasher.hash(), description, constructorArg, typeCoercerFactory, factoryParams, declaredDeps.build(), visibilityPatterns.build(), targetCell.getCellRoots()); nodeListener.onCreate(buildFile, node); return node; } } catch (NoSuchBuildTargetException | TargetNode.InvalidSourcePathInputException e) { throw new HumanReadableException(e); } catch (ConstructorArgMarshalException e) { throw new HumanReadableException("%s: %s", target, e.getMessage()); } catch (IOException e) { throw new HumanReadableException(e.getMessage(), e); } }
@Test public void canPopulateSimpleConstructorArgFromBuildFactoryParams() throws ConstructorArgMarshalException, NoSuchBuildTargetException { class Dto { public String required; public Optional<String> notRequired; public int num; // Turns out there no optional number params // public Optional<Long> optionalLong; public boolean needed; public Optional<Boolean> notNeeded; public SourcePath aSrcPath; public Optional<SourcePath> notASrcPath; public Path aPath; public Optional<Path> notAPath; } ProjectFilesystem projectFilesystem = new FakeProjectFilesystem(); FakeBuildRule expectedRule = new FakeBuildRule( BuildTargetFactory.newInstance("//example/path:path"), new SourcePathResolver(new BuildRuleResolver())); ruleResolver.addToIndex(expectedRule); ImmutableMap<String, Object> args = ImmutableMap.<String, Object>builder() .put("required", "cheese") .put("notRequired", "cake") // Long because that's what comes from python. .put("num", 42L) // Skipping optional Long. .put("needed", true) // Skipping optional boolean. .put("aSrcPath", ":path") .put("aPath", "./File.java") .put("notAPath", "./NotFile.java") .build(); Dto dto = new Dto(); marshaller.populate( createCellRoots(filesystem), filesystem, buildRuleFactoryParams(), dto, ImmutableSet.<BuildTarget>builder(), ImmutableSet.<BuildTargetPattern>builder(), args); assertEquals("cheese", dto.required); assertEquals("cake", dto.notRequired.get()); assertEquals(42, dto.num); assertTrue(dto.needed); assertEquals(Optional.<Boolean>absent(), dto.notNeeded); BuildTargetSourcePath expected = new BuildTargetSourcePath(expectedRule.getBuildTarget()); assertEquals(expected, dto.aSrcPath); assertEquals(Paths.get("example/path/NotFile.java"), dto.notAPath.get()); }