blob: 549f645e4b27f0945cdfd3ed8a4343dc95f5a890 [file] [log] [blame]
/*
* Copyright 2013-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package com.facebook.buck.rules.coercer;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.sameInstance;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.Pair;
import com.facebook.buck.parser.BuildTargetParser;
import com.facebook.buck.rules.ImmutableLabel;
import com.facebook.buck.rules.Label;
import com.facebook.buck.rules.SourcePath;
import com.facebook.buck.rules.TestSourcePath;
import com.facebook.buck.testutil.FakeProjectFilesystem;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Lists;
import org.hamcrest.Matcher;
import org.hamcrest.Matchers;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import java.io.IOException;
import java.lang.reflect.Type;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class TypeCoercerTest {
private final TypeCoercerFactory typeCoercerFactory = new TypeCoercerFactory();
private final BuildTargetParser targetParser = new BuildTargetParser();
private final FakeProjectFilesystem filesystem = new FakeProjectFilesystem();
@Rule
public ExpectedException exception = ExpectedException.none();
@Test
public void coercingStringMapOfIntListsShouldBeIdentity()
throws CoerceFailedException, NoSuchFieldException {
Type type = TestFields.class.getField("stringMapOfLists").getGenericType();
TypeCoercer<?> coercer = typeCoercerFactory.typeCoercerForType(type);
ImmutableMap<String, ImmutableList<Integer>> input =
ImmutableMap.of(
"foo", ImmutableList.of(4, 5),
"bar", ImmutableList.of(6, 7));
Object result = coercer.coerce(targetParser, filesystem, Paths.get(""), input);
assertEquals(input, result);
}
@Test
public void coercingNestedListOfSetsShouldActuallyCreateSets()
throws CoerceFailedException, NoSuchFieldException {
Type type = TestFields.class.getField("listOfSets").getGenericType();
TypeCoercer<?> coercer = typeCoercerFactory.typeCoercerForType(type);
ImmutableList<ImmutableList<Integer>> input =
ImmutableList.of(
ImmutableList.of(4, 4, 5),
ImmutableList.of(6, 7));
Object result = coercer.coerce(targetParser, filesystem, Paths.get(""), input);
ImmutableList<ImmutableSet<Integer>> expectedResult =
ImmutableList.of(
ImmutableSet.of(4, 5),
ImmutableSet.of(6, 7));
assertEquals(expectedResult, result);
}
@Test
public void coercingSortedSetsShouldThrowOnDuplicates()
throws CoerceFailedException, NoSuchFieldException {
Type type = TestFields.class.getField("sortedSetOfStrings").getGenericType();
TypeCoercer<?> coercer = typeCoercerFactory.typeCoercerForType(type);
ImmutableList<String> input = ImmutableList.of("a", "a");
try {
coercer.coerce(targetParser, filesystem, Paths.get(""), input);
fail();
} catch (CoerceFailedException e) {
assertEquals("duplicate element \"a\"", e.getMessage());
}
}
@Test
public void coercingSortedSetsShouldActuallyCreateSortedSets()
throws CoerceFailedException, NoSuchFieldException {
Type type = TestFields.class.getField("sortedSetOfStrings").getGenericType();
TypeCoercer<?> coercer = typeCoercerFactory.typeCoercerForType(type);
ImmutableList<String> input = ImmutableList.of("c", "a", "d", "b");
Object result = coercer.coerce(targetParser, filesystem, Paths.get(""), input);
ImmutableSortedSet<String> expectedResult = ImmutableSortedSet.copyOf(input);
assertEquals(expectedResult, result);
}
@Test
public void shouldAllowListTypeToBeSuperclassOfResult()
throws CoerceFailedException, NoSuchFieldException {
Type type = TestFields.class.getField("superclassOfImmutableList").getGenericType();
TypeCoercer<?> coercer = typeCoercerFactory.typeCoercerForType(type);
ImmutableList<String> input = ImmutableList.of("a", "b", "c");
Object result = coercer.coerce(targetParser, filesystem, Paths.get(""), input);
assertEquals(ImmutableList.of("a", "b", "c"), result);
}
@Test
public void shouldAllowMapTypeToBeSuperclassOfResult()
throws CoerceFailedException, NoSuchFieldException {
Type type = TestFields.class.getField("superclassOfImmutableMap").getGenericType();
TypeCoercer<?> coercer = typeCoercerFactory.typeCoercerForType(type);
ImmutableMap<String, String> input = ImmutableMap.of("a", "b");
Object result = coercer.coerce(targetParser, filesystem, Paths.get(""), input);
assertEquals(input, result);
}
/**
* Cannot declare a field that is not a superclass (i.e. LinkedList instead of List or
* ImmutableList). Required as TypeCoercer will assign an ImmutableList.
*/
@Test(expected = IllegalArgumentException.class)
public void disallowSubclassOfSuperclass() throws NoSuchFieldException {
Type type = TestFields.class.getField("subclassOfList").getGenericType();
typeCoercerFactory.typeCoercerForType(type);
}
/**
* Specifying a field type that matches too many coercers should be disallowed.
*/
@Test(expected = IllegalArgumentException.class)
public void disallowAmbiguousSimpleTypes() throws NoSuchFieldException {
Type type = TestFields.class.getField("object").getGenericType();
typeCoercerFactory.typeCoercerForType(type);
}
@Test(expected = IllegalArgumentException.class)
public void disallowMapWithOptionalKeys() throws NoSuchFieldException {
Type type = TestFields.class.getField("optionalIntegerMapOfStrings").getGenericType();
typeCoercerFactory.typeCoercerForType(type);
}
/**
* Traverse visits every element of an input value without coercing to the output type.
*/
@Test
public void traverseShouldVisitEveryObject() throws NoSuchFieldException {
Type type = TestFields.class.getField("stringMapOfLists").getGenericType();
@SuppressWarnings("unchecked")
TypeCoercer<ImmutableMap<String, ImmutableList<String>>> coercer =
(TypeCoercer<ImmutableMap<String, ImmutableList<String>>>)
typeCoercerFactory.typeCoercerForType(type);
final ImmutableMap<String, ImmutableList<String>> input =
ImmutableMap.of(
"foo", ImmutableList.of("//foo:bar", "//foo:baz"),
"bar", ImmutableList.of(":bar", "//foo:foo"));
TestTraversal traversal = new TestTraversal();
coercer.traverse(input, traversal);
Matcher<Iterable<?>> matcher = Matchers.contains(
ImmutableList.<Matcher<? super Object>>of(
sameInstance((Object) input),
is((Object) "foo"),
sameInstance((Object) input.get("foo")),
is((Object) "//foo:bar"),
is((Object) "//foo:baz"),
is((Object) "bar"),
sameInstance((Object) input.get("bar")),
is((Object) ":bar"),
is((Object) "//foo:foo")));
assertThat(traversal.getObjects(), matcher);
}
@Test
public void hasElementTypesForContainers() throws NoSuchFieldException {
Type type = TestFields.class.getField("stringMapOfLists").getGenericType();
TypeCoercer<?> coercer = typeCoercerFactory.typeCoercerForType(type);
assertTrue(coercer.hasElementClass(String.class));
assertTrue(coercer.hasElementClass(Integer.class));
assertTrue(coercer.hasElementClass(Integer.class, String.class));
assertTrue(coercer.hasElementClass(Integer.class, SourcePath.class));
assertFalse(coercer.hasElementClass(SourcePath.class));
}
@Test
public void hasElementTypesForPrimitives() throws NoSuchFieldException {
Type type = TestFields.class.getField("primitiveString").getGenericType();
TypeCoercer<?> coercer = typeCoercerFactory.typeCoercerForType(type);
assertTrue(coercer.hasElementClass(String.class));
assertFalse(coercer.hasElementClass(Integer.class));
}
@Test
public void coerceToEitherLeftOrRight() throws NoSuchFieldException, CoerceFailedException {
Type type = TestFields.class.getField("eitherStringSetOrStringToStringMap").getGenericType();
TypeCoercer<?> coercer = typeCoercerFactory.typeCoercerForType(type);
Set<String> inputSet = ImmutableSet.of("a", "b", "x");
Map<String, String> inputMap = ImmutableMap.of(
"key1", "One",
"key2", "Two");
assertEquals(
Either.ofLeft(inputSet),
coercer.coerce(targetParser, filesystem, Paths.get(""), inputSet));
assertEquals(
Either.ofRight(inputMap),
coercer.coerce(targetParser, filesystem, Paths.get(""), inputMap));
}
@Test
public void coercedEitherThrowsOnAccessingMissingLeft()
throws NoSuchFieldException, CoerceFailedException {
Type type = TestFields.class.getField("eitherStringSetOrStringToStringMap").getGenericType();
TypeCoercer<?> coercer = typeCoercerFactory.typeCoercerForType(type);
Map<String, String> inputMap = ImmutableMap.of(
"key1", "One",
"key2", "Two");
Either<?, ?> either = (Either<?, ?>)
coercer.coerce(targetParser, filesystem, Paths.get(""), inputMap);
assertEquals(inputMap, either.getRight());
exception.expect(RuntimeException.class);
either.getLeft();
}
@Test
public void coercedEitherThrowsOnAccessingMissingRight()
throws NoSuchFieldException, CoerceFailedException {
Type type = TestFields.class.getField("eitherStringSetOrStringToStringMap").getGenericType();
TypeCoercer<?> coercer = typeCoercerFactory.typeCoercerForType(type);
Set<String> inputSet = ImmutableSet.of("a", "b", "x");
Either<?, ?> either = (Either<?, ?>)
coercer.coerce(targetParser, filesystem, Paths.get(""), inputSet);
assertEquals(inputSet, either.getLeft());
exception.expect(RuntimeException.class);
either.getRight();
}
@Test
public void coerceToEitherLeftOrRightWithCollections()
throws NoSuchFieldException, CoerceFailedException {
Type type = TestFields.class.getField("eitherStringOrStringList").getGenericType();
TypeCoercer<?> coercer = typeCoercerFactory.typeCoercerForType(type);
String inputString = "a_string";
ImmutableList<String> inputList = ImmutableList.of("a", "b");
assertEquals(
Either.ofLeft(inputString),
coercer.coerce(targetParser, filesystem, Paths.get(""), inputString));
assertEquals(
Either.ofRight(inputList),
coercer.coerce(targetParser, filesystem, Paths.get(""), inputList));
}
@Test
public void traverseWithEitherAndContainer() throws NoSuchFieldException {
Type type = TestFields.class.getField("eitherStringOrStringList").getGenericType();
@SuppressWarnings("unchecked")
TypeCoercer<Either<String, List<String>>> coercer =
(TypeCoercer<Either<String, List<String>>>) typeCoercerFactory.typeCoercerForType(type);
TestTraversal traversal = new TestTraversal();
Either<String, List<String>> input = Either.ofRight((List<String>) ImmutableList.of("foo"));
coercer.traverse(input, traversal);
assertThat(
traversal.getObjects(),
Matchers.contains(ImmutableList.<Matcher<? super Object>>of(
sameInstance((Object) input.getRight()),
sameInstance((Object) input.getRight().get(0)))));
traversal = new TestTraversal();
Either<String, List<String>> input2 = Either.ofLeft("foo");
coercer.traverse(input2, traversal);
assertThat(traversal.getObjects(), hasSize(1));
assertThat(traversal.getObjects().get(0), sameInstance((Object) "foo"));
}
static class TestTraversal implements TypeCoercer.Traversal {
private List<Object> objects = Lists.newArrayList();
public List<Object> getObjects() {
return objects;
}
@Override
public void traverse(Object object) {
objects.add(object);
}
}
@Test
public void pairTypeCoercerCanCoerceFromTwoElementLists()
throws NoSuchFieldException, CoerceFailedException {
Type type = TestFields.class.getField("pairOfPathsAndStrings").getGenericType();
TypeCoercer<?> coercer = typeCoercerFactory.typeCoercerForType(type);
ImmutableList<?> input = ImmutableList.of("foo.m", "-foo -bar");
assertEquals(
new Pair<>(Paths.get("foo.m"), "-foo -bar"),
coercer.coerce(targetParser, filesystem, Paths.get(""), input));
}
@Test
public void hasElementTypesForPair() throws NoSuchFieldException {
Type type = TestFields.class.getField("pairOfPathsAndStrings").getGenericType();
TypeCoercer<?> coercer = typeCoercerFactory.typeCoercerForType(type);
assertTrue(coercer.hasElementClass(String.class));
assertTrue(coercer.hasElementClass(Path.class));
assertFalse(coercer.hasElementClass(Integer.class));
}
@Test
public void traverseWithPair() throws NoSuchFieldException {
Type type = TestFields.class.getField("pairOfPathsAndStrings").getGenericType();
@SuppressWarnings("unchecked")
TypeCoercer<Pair<Path, String>> coercer =
(TypeCoercer<Pair<Path, String>>) typeCoercerFactory.typeCoercerForType(type);
TestTraversal traversal = new TestTraversal();
Pair<Path, String> input = new Pair<>(Paths.get("foo"), "bar");
coercer.traverse(input, traversal);
assertThat(
traversal.getObjects(),
Matchers.contains(
ImmutableList.<Matcher<? super Object>>of(
sameInstance((Object) input.getFirst()),
sameInstance((Object) input.getSecond()))));
}
@Test
public void coercingAppleSourcePaths() throws NoSuchFieldException, CoerceFailedException {
Type type = TestFields.class.getField("listOfSourcesWithFlags").getGenericType();
TypeCoercer<?> coercer = typeCoercerFactory.typeCoercerForType(type);
ImmutableList<String> input = ImmutableList.of("foo.m", "bar.m");
Object result = coercer.coerce(targetParser, filesystem, Paths.get(""), input);
ImmutableList<SourceWithFlags> expectedResult = ImmutableList.of(
SourceWithFlags.of(new TestSourcePath("foo.m")),
SourceWithFlags.of(new TestSourcePath("bar.m")));
assertEquals(expectedResult, result);
}
@Test
public void coercingAppleSourcePathsWithFlags()
throws NoSuchFieldException, CoerceFailedException {
Type type = TestFields.class.getField("listOfSourcesWithFlags").getGenericType();
TypeCoercer<?> coercer = typeCoercerFactory.typeCoercerForType(type);
ImmutableList<?> input = ImmutableList.of(
ImmutableList.of("foo.m", ImmutableList.of("-Wall", "-Werror")),
ImmutableList.of("bar.m", ImmutableList.of("-fobjc-arc")));
Object result = coercer.coerce(targetParser, filesystem, Paths.get(""), input);
ImmutableList<SourceWithFlags> expectedResult = ImmutableList.of(
SourceWithFlags.of(
new TestSourcePath("foo.m"), ImmutableList.of("-Wall", "-Werror")),
SourceWithFlags.of(
new TestSourcePath("bar.m"), ImmutableList.of("-fobjc-arc")));
assertEquals(expectedResult, result);
}
@Test
public void coercingHeterogeneousAppleSourceGroups()
throws NoSuchFieldException, CoerceFailedException {
Type type = TestFields.class.getField("listOfSourcesWithFlags").getGenericType();
TypeCoercer<?> coercer = typeCoercerFactory.typeCoercerForType(type);
ImmutableList<?> input = ImmutableList.of(
"Group1/foo.m",
ImmutableList.of("Group1/bar.m", ImmutableList.of("-Wall", "-Werror")),
"Group2/baz.m",
ImmutableList.of("Group2/blech.m", ImmutableList.of("-fobjc-arc")));
Object result = coercer.coerce(targetParser, filesystem, Paths.get(""), input);
ImmutableList<SourceWithFlags> expectedResult = ImmutableList.of(
SourceWithFlags.of(new TestSourcePath("Group1/foo.m")),
SourceWithFlags.of(
new TestSourcePath("Group1/bar.m"), ImmutableList.of("-Wall", "-Werror")),
SourceWithFlags.of(new TestSourcePath("Group2/baz.m")),
SourceWithFlags.of(
new TestSourcePath("Group2/blech.m"), ImmutableList.of("-fobjc-arc")));
assertEquals(expectedResult, result);
}
@Test
public void coerceToLabels() throws NoSuchFieldException, CoerceFailedException {
Type type = TestFields.class.getField("labels").getGenericType();
TypeCoercer<?> coercer = typeCoercerFactory.typeCoercerForType(type);
ImmutableList<String> input = ImmutableList.of("cheese", "cake", "tastes", "good");
Object result = coercer.coerce(targetParser, filesystem, Paths.get(""), input);
ImmutableSortedSet<Label> expected = ImmutableSortedSet.<Label>of(
ImmutableLabel.of("cake"),
ImmutableLabel.of("cheese"),
ImmutableLabel.of("good"),
ImmutableLabel.of("tastes"));
assertEquals(expected, result);
}
@Test
public void coerceToEnumShouldWorkInList()
throws NoSuchFieldException, CoerceFailedException {
Type type = TestFields.class.getField("listOfTestEnums").getGenericType();
TypeCoercer<?> coercer = typeCoercerFactory.typeCoercerForType(type);
ImmutableList<String> input = ImmutableList.of("PURPLE", "RED", "RED", "PURPLE");
Object result = coercer.coerce(targetParser, filesystem, Paths.get(""), input);
ImmutableList<TestEnum> expected =
ImmutableList.of(TestEnum.PURPLE, TestEnum.RED, TestEnum.RED, TestEnum.PURPLE);
assertEquals(expected, result);
}
@Test
public void coerceToEnumShouldWorkInSet()
throws NoSuchFieldException, CoerceFailedException {
Type type = TestFields.class.getField("setOfTestEnums").getGenericType();
TypeCoercer<?> coercer = typeCoercerFactory.typeCoercerForType(type);
ImmutableSet<String> input = ImmutableSet.of("PURPLE", "PINK", "RED");
Object result = coercer.coerce(targetParser, filesystem, Paths.get(""), input);
ImmutableSet<TestEnum> expected =
ImmutableSet.of(TestEnum.PURPLE, TestEnum.PINK, TestEnum.RED);
assertEquals(expected, result);
}
@Test
public void coerceToEnumsShouldWorkWithUpperAndLowerCaseValues()
throws NoSuchFieldException, CoerceFailedException {
Type type = TestFields.class.getField("listOfTestEnums").getGenericType();
TypeCoercer<?> coercer = typeCoercerFactory.typeCoercerForType(type);
ImmutableList<String> input = ImmutableList.of("grey", "YELLOW", "red", "PURPLE");
Object result = coercer.coerce(targetParser, filesystem, Paths.get(""), input);
ImmutableList<TestEnum> expected =
ImmutableList.of(TestEnum.grey, TestEnum.yellow, TestEnum.RED, TestEnum.PURPLE);
assertEquals(expected, result);
}
@Test
public void coerceFromTurkishIsShouldWork()
throws NoSuchFieldException, CoerceFailedException {
Type type = TestFields.class.getField("listOfTestEnums").getGenericType();
TypeCoercer<?> coercer = typeCoercerFactory.typeCoercerForType(type);
String pinkWithLowercaseTurkishI = "p\u0131nk";
String pinkWithUppercaseTurkishI = "P\u0130NK";
String whiteWithLowercaseTurkishI = "wh\u0131te";
String whiteWithUppercaseTurkishI = "WH\u0130TE";
ImmutableList<String> input = ImmutableList.of(pinkWithLowercaseTurkishI,
pinkWithUppercaseTurkishI, whiteWithLowercaseTurkishI, whiteWithUppercaseTurkishI);
ImmutableList<TestEnum> expected = ImmutableList.of(
TestEnum.PINK, TestEnum.PINK, TestEnum.white, TestEnum.white);
Object result = coercer.coerce(targetParser, filesystem, Paths.get(""), input);
assertEquals(expected, result);
}
@Test
public void coerceToTurkishIsShouldWork()
throws NoSuchFieldException, CoerceFailedException {
Type type = TestFields.class.getField("listOfTestEnums").getGenericType();
TypeCoercer<?> coercer = typeCoercerFactory.typeCoercerForType(type);
String violetWithLowerCaseTurkishI = "v\u0131olet";
String violetWithUpperCaseTurkishI = "V\u0130OLET";
ImmutableList<String> input = ImmutableList.of(
"violet", "VIOLET", violetWithLowerCaseTurkishI, violetWithUpperCaseTurkishI);
ImmutableList<TestEnum> expected = ImmutableList.of(
TestEnum.VIOLET, TestEnum.VIOLET, TestEnum.VIOLET, TestEnum.VIOLET
);
Object result = coercer.coerce(targetParser, filesystem, Paths.get(""), input);
assertEquals(expected, result);
}
@Test
public void invalidSourcePathShouldGiveSpecificErrorMsg()
throws NoSuchFieldException, IOException {
Type type = TestFields.class.getField("setOfSourcePaths").getGenericType();
TypeCoercer<?> coercer = typeCoercerFactory.typeCoercerForType(type);
Path baratheon = Paths.get("Baratheon.java");
Path lannister = Paths.get("Lannister.java");
Path stark = Paths.get("Stark.java");
Path targaryen = Paths.get("Targaryen.java");
ImmutableList<Path> input =
ImmutableList.of(baratheon, lannister, stark, targaryen);
for (Path p : input) {
if (!p.equals(baratheon)) {
filesystem.touch(p);
}
}
try {
coercer.coerce(targetParser, filesystem, Paths.get(""), input);
} catch (CoerceFailedException e) {
String result = e.getMessage();
String expected = "cannot coerce 'Baratheon.java'";
for (Path p : input) {
if (!p.equals(baratheon)) {
assertFalse(result.contains(p.toString()));
}
}
assertTrue(result.contains(expected));
}
}
private CoerceFailedException getCoerceException(Type type, Object object) {
// First just coerce the raw type and save the coercion exception that gets thrown.
TypeCoercer<?> coercer = typeCoercerFactory.typeCoercerForType(type);
try {
coercer.coerce(targetParser, filesystem, Paths.get(""), object);
fail("should throw");
throw new RuntimeException(); // Suppress "missing return statement" errors
} catch (CoerceFailedException e) {
return e;
}
}
private void assertSameMessage(Exception e1, Exception e2) {
assertEquals(e1.getMessage(), e2.getMessage());
}
@Test
public void coerceToContainerTypesShouldNotHideInnerCoerceExceptions()
throws NoSuchFieldException {
// A string representation of an invalid path, which throws an error when
// coercing to a `Path` type.
String invalidPath = "";
CoerceFailedException pathCoerceException = getCoerceException(Path.class, invalidPath);
// Verify that the various collection and map types don't mask inner coercion errors.
assertSameMessage(
pathCoerceException,
getCoerceException(
TestFields.class.getField("stringMapOfPaths").getGenericType(),
ImmutableMap.of("test", invalidPath)));
assertSameMessage(
pathCoerceException,
getCoerceException(
TestFields.class.getField("listOfPaths").getGenericType(),
ImmutableList.of(invalidPath)));
assertSameMessage(
pathCoerceException,
getCoerceException(
TestFields.class.getField("sortedSetOfPaths").getGenericType(),
ImmutableList.of(invalidPath)));
assertSameMessage(
pathCoerceException,
getCoerceException(
TestFields.class.getField("setOfPaths").getGenericType(),
ImmutableList.of(invalidPath)));
// Test that `SourcePath` coercion doesn't change the error from `Path` cercion.
assertSameMessage(
pathCoerceException,
getCoerceException(SourcePath.class, invalidPath));
// Test that regardless of order, we get the same invalid path coercion error
// when trying to coerce a path-y object.
assertSameMessage(
pathCoerceException,
getCoerceException(
TestFields.class.getField("eitherListOfStringsOrPath").getGenericType(),
invalidPath));
assertSameMessage(
pathCoerceException,
getCoerceException(
TestFields.class.getField("eitherPathOrListOfStrings").getGenericType(),
invalidPath));
// Test that regardless of order, we get the same invalid list-of-strings
// coercion error when trying to coerce a list object.
ImmutableList<Integer> invalidListOfStrings = ImmutableList.of(1, 4, 5);
CoerceFailedException listOfStringsException = getCoerceException(
TestFields.class.getField("listOfStrings").getGenericType(),
invalidListOfStrings);
assertSameMessage(
listOfStringsException,
getCoerceException(
TestFields.class.getField("eitherListOfStringsOrPath").getGenericType(),
invalidListOfStrings));
assertSameMessage(
listOfStringsException,
getCoerceException(
TestFields.class.getField("eitherPathOrListOfStrings").getGenericType(),
invalidListOfStrings));
}
static class TestFields {
public ImmutableMap<String, ImmutableList<Integer>> stringMapOfLists;
public ImmutableList<ImmutableSet<Integer>> listOfSets;
public ImmutableSet<SourcePath> setOfSourcePaths;
public ImmutableSortedSet<String> sortedSetOfStrings;
public List<String> superclassOfImmutableList;
public Map<String, String> superclassOfImmutableMap;
@SuppressWarnings("PMD.LooseCoupling")
public LinkedList<Integer> subclassOfList;
public Object object;
public ImmutableMap<String, ImmutableList<BuildTarget>> stringMapOfListOfBuildTargets;
public Map<Optional<Integer>, String> optionalIntegerMapOfStrings;
public String primitiveString;
public Either<String, List<String>> eitherStringOrStringList;
public Either<Set<String>, Map<String, String>> eitherStringSetOrStringToStringMap;
public Pair<Path, String> pairOfPathsAndStrings;
public ImmutableList<SourceWithFlags> listOfSourcesWithFlags;
public ImmutableSortedSet<Label> labels;
public ImmutableList<TestEnum> listOfTestEnums;
public ImmutableMap<String, Path> stringMapOfPaths;
public ImmutableList<Path> listOfPaths;
public ImmutableSortedSet<Path> sortedSetOfPaths;
public ImmutableSet<Path> setOfPaths;
public ImmutableList<String> listOfStrings;
public Either<Path, ImmutableList<String>> eitherPathOrListOfStrings;
public Either<ImmutableList<String>, Path> eitherListOfStringsOrPath;
public ImmutableSet<TestEnum> setOfTestEnums;
}
private static enum TestEnum { RED, PURPLE, yellow, grey, PINK, white, VIOLET }
}