|
63 | 63 | import java.util.List; |
64 | 64 | import java.util.Map; |
65 | 65 | import java.util.Set; |
| 66 | +import java.util.function.Consumer; |
| 67 | +import java.util.function.Function; |
66 | 68 | import java.util.jar.JarOutputStream; |
67 | 69 | import java.util.zip.ZipEntry; |
68 | 70 |
|
@@ -828,6 +830,68 @@ public <T> void testSatisfiesMatchingT() { |
828 | 830 | assertNotEquals(Types.satisfies(argsMiss, params), -1); |
829 | 831 |
|
830 | 832 | } |
| 833 | + |
| 834 | + /** |
| 835 | + * Tests {@link Types#satisfies(Type[], Type[])} when the given type is indirectly parameterized by |
| 836 | + * implementing an parameterized interface. |
| 837 | + */ |
| 838 | + @Test |
| 839 | + public <I1, I2> void testSatisfiesIndirectTypeVariables() { |
| 840 | + |
| 841 | + class NestedThingImplOK1 implements NestedThing<Double, Double> { |
| 842 | + @Override |
| 843 | + public Double apply(Double t) { |
| 844 | + // NB: No implementation needed. |
| 845 | + return null; |
| 846 | + } |
| 847 | + } |
| 848 | + |
| 849 | + final Type[] param = new Type[]{new Nil<Function<I1, I2>>() {}.getType()}; |
| 850 | + Type[] argOK = new Type[]{NestedThingImplOK1.class}; |
| 851 | + assertEquals(-1, Types.satisfies(argOK, param)); |
| 852 | + } |
| 853 | + |
| 854 | + /** |
| 855 | + * Tests {@link Types#satisfies(Type[], Type[])} when unbounded type variables are expected |
| 856 | + * but the given ones are nested and bounded. |
| 857 | + */ |
| 858 | + @Test |
| 859 | + public <I1, I2> void testSatisfiesUnboundedTypeVariables() { |
| 860 | + |
| 861 | + class NestedThingImplOK1 implements Function<Iterable<Double>, Consumer<Double>> { |
| 862 | + @Override |
| 863 | + public Consumer<Double> apply(Iterable<Double> t) { |
| 864 | + // NB: No implementation needed. |
| 865 | + return null; |
| 866 | + } |
| 867 | + } |
| 868 | + |
| 869 | + class NestedThingImplOK2 implements Function<Iterable<Double>, Consumer<Integer>> { |
| 870 | + @Override |
| 871 | + public Consumer<Integer> apply(Iterable<Double> t) { |
| 872 | + // NB: No implementation needed. |
| 873 | + return null; |
| 874 | + } |
| 875 | + } |
| 876 | + |
| 877 | + class NestedThingImplOK3 implements Function<Double, Consumer<Integer>> { |
| 878 | + @Override |
| 879 | + public Consumer<Integer> apply(Double t) { |
| 880 | + // NB: No implementation needed. |
| 881 | + return null; |
| 882 | + } |
| 883 | + } |
| 884 | + |
| 885 | + final Type[] param = new Type[]{new Nil<Function<I1, I2>>() {}.getType()}; |
| 886 | + Type[] argOK = new Type[]{NestedThingImplOK1.class}; |
| 887 | + assertEquals(-1, Types.satisfies(argOK, param)); |
| 888 | + |
| 889 | + argOK = new Type[]{NestedThingImplOK2.class}; |
| 890 | + assertEquals(-1, Types.satisfies(argOK, param)); |
| 891 | + |
| 892 | + final Type[] argNotOK = new Type[]{NestedThingImplOK3.class}; |
| 893 | + assertEquals(-1, Types.satisfies(argNotOK, param)); |
| 894 | + } |
831 | 895 |
|
832 | 896 | /** Tests {@link Types#cast(Object, Class)}. */ |
833 | 897 | @Test |
@@ -951,6 +1015,11 @@ private static class LoopingThing extends RecursiveThing<LoopingThing> |
951 | 1015 | { |
952 | 1016 | // NB: No implementation needed. |
953 | 1017 | } |
| 1018 | + |
| 1019 | + interface NestedThing<I1, I2> extends Function<I1, I2> |
| 1020 | + { |
| 1021 | + // NB: No implementation needed. |
| 1022 | + } |
954 | 1023 |
|
955 | 1024 | /** Enumeration for testing conversion to enum types. */ |
956 | 1025 | public static enum Words { |
|
0 commit comments