/***********************************************************************************************************************
*
* Copyright (C) 2010-2013 by the Stratosphere project (http://stratosphere.eu)
*
* 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 eu.stratosphere.api.java.type.extractor;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.Iterator;
import org.junit.Assert;
import org.junit.Test;
import eu.stratosphere.api.java.functions.CoGroupFunction;
import eu.stratosphere.api.java.functions.CrossFunction;
import eu.stratosphere.api.java.functions.FlatMapFunction;
import eu.stratosphere.api.java.functions.GroupReduceFunction;
import eu.stratosphere.api.java.functions.InvalidTypesException;
import eu.stratosphere.api.java.functions.JoinFunction;
import eu.stratosphere.api.java.functions.KeySelector;
import eu.stratosphere.api.java.functions.MapFunction;
import eu.stratosphere.api.java.tuple.Tuple;
import eu.stratosphere.api.java.tuple.Tuple1;
import eu.stratosphere.api.java.tuple.Tuple2;
import eu.stratosphere.api.java.tuple.Tuple3;
import eu.stratosphere.api.java.tuple.Tuple9;
import eu.stratosphere.api.java.typeutils.BasicArrayTypeInfo;
import eu.stratosphere.api.java.typeutils.BasicTypeInfo;
import eu.stratosphere.api.java.typeutils.GenericTypeInfo;
import eu.stratosphere.api.java.typeutils.ObjectArrayTypeInfo;
import eu.stratosphere.api.java.typeutils.ResultTypeQueryable;
import eu.stratosphere.api.java.typeutils.TupleTypeInfo;
import eu.stratosphere.api.java.typeutils.TypeExtractor;
import eu.stratosphere.api.java.typeutils.TypeInfoParser;
import eu.stratosphere.api.java.typeutils.ValueTypeInfo;
import eu.stratosphere.api.java.typeutils.WritableTypeInfo;
import eu.stratosphere.types.DoubleValue;
import eu.stratosphere.types.IntValue;
import eu.stratosphere.types.StringValue;
import eu.stratosphere.types.TypeInformation;
import eu.stratosphere.types.Value;
import eu.stratosphere.util.Collector;
import org.apache.hadoop.io.Writable;
public class TypeExtractorTest {
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void testBasicType() {
// use getGroupReduceReturnTypes()
GroupReduceFunction<?, ?> function = new GroupReduceFunction<Boolean, Boolean>() {
private static final long serialVersionUID = 1L;
@Override
public void reduce(Iterator<Boolean> values, Collector<Boolean> out) throws Exception {
// nothing to do
}
};
TypeInformation<?> ti = TypeExtractor.getGroupReduceReturnTypes(function, (TypeInformation) TypeInfoParser.parse("Boolean"));
Assert.assertTrue(ti.isBasicType());
Assert.assertEquals(BasicTypeInfo.BOOLEAN_TYPE_INFO, ti);
Assert.assertEquals(Boolean.class, ti.getTypeClass());
// use getForClass()
Assert.assertTrue(TypeExtractor.getForClass(Boolean.class).isBasicType());
Assert.assertEquals(ti, TypeExtractor.getForClass(Boolean.class));
// use getForObject()
Assert.assertEquals(BasicTypeInfo.BOOLEAN_TYPE_INFO, TypeExtractor.getForObject(Boolean.valueOf(true)));
}
public static class MyWritable implements Writable {
@Override
public void write(DataOutput out) throws IOException {
}
@Override
public void readFields(DataInput in) throws IOException {
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testWritableType() {
MapFunction<?, ?> function = new MapFunction<MyWritable, MyWritable>() {
private static final long serialVersionUID = 1L;
@Override
public MyWritable map(MyWritable value) throws Exception {
return null;
}
};
TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(function, (TypeInformation) new WritableTypeInfo<MyWritable>(MyWritable.class));
Assert.assertTrue(ti instanceof WritableTypeInfo<?>);
Assert.assertEquals(MyWritable.class, ((WritableTypeInfo<?>) ti).getTypeClass());
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testTupleWithBasicTypes() throws Exception {
// use getMapReturnTypes()
MapFunction<?, ?> function = new MapFunction<Tuple9<Integer, Long, Double, Float, Boolean, String, Character, Short, Byte>, Tuple9<Integer, Long, Double, Float, Boolean, String, Character, Short, Byte>>() {
private static final long serialVersionUID = 1L;
@Override
public Tuple9<Integer, Long, Double, Float, Boolean, String, Character, Short, Byte> map(
Tuple9<Integer, Long, Double, Float, Boolean, String, Character, Short, Byte> value) throws Exception {
return null;
}
};
TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(function, (TypeInformation) TypeInfoParser.parse("Tuple9<Integer, Long, Double, Float, Boolean, String, Character, Short, Byte>"));
Assert.assertTrue(ti.isTupleType());
Assert.assertEquals(9, ti.getArity());
Assert.assertTrue(ti instanceof TupleTypeInfo);
TupleTypeInfo<?> tti = (TupleTypeInfo<?>) ti;
Assert.assertEquals(Tuple9.class, tti.getTypeClass());
for (int i = 0; i < 9; i++) {
Assert.assertTrue(tti.getTypeAt(i) instanceof BasicTypeInfo);
}
Assert.assertEquals(BasicTypeInfo.INT_TYPE_INFO, tti.getTypeAt(0));
Assert.assertEquals(BasicTypeInfo.LONG_TYPE_INFO, tti.getTypeAt(1));
Assert.assertEquals(BasicTypeInfo.DOUBLE_TYPE_INFO, tti.getTypeAt(2));
Assert.assertEquals(BasicTypeInfo.FLOAT_TYPE_INFO, tti.getTypeAt(3));
Assert.assertEquals(BasicTypeInfo.BOOLEAN_TYPE_INFO, tti.getTypeAt(4));
Assert.assertEquals(BasicTypeInfo.STRING_TYPE_INFO, tti.getTypeAt(5));
Assert.assertEquals(BasicTypeInfo.CHAR_TYPE_INFO, tti.getTypeAt(6));
Assert.assertEquals(BasicTypeInfo.SHORT_TYPE_INFO, tti.getTypeAt(7));
Assert.assertEquals(BasicTypeInfo.BYTE_TYPE_INFO, tti.getTypeAt(8));
// use getForObject()
Tuple9<Integer, Long, Double, Float, Boolean, String, Character, Short, Byte> t = new Tuple9<Integer, Long, Double, Float, Boolean, String, Character, Short, Byte>(
1, 1L, 1.0, 1.0F, false, "Hello World", 'w', (short) 1, (byte) 1);
Assert.assertTrue(TypeExtractor.getForObject(t) instanceof TupleTypeInfo);
TupleTypeInfo<?> tti2 = (TupleTypeInfo<?>) TypeExtractor.getForObject(t);
Assert.assertEquals(BasicTypeInfo.INT_TYPE_INFO, tti2.getTypeAt(0));
Assert.assertEquals(BasicTypeInfo.LONG_TYPE_INFO, tti2.getTypeAt(1));
Assert.assertEquals(BasicTypeInfo.DOUBLE_TYPE_INFO, tti2.getTypeAt(2));
Assert.assertEquals(BasicTypeInfo.FLOAT_TYPE_INFO, tti2.getTypeAt(3));
Assert.assertEquals(BasicTypeInfo.BOOLEAN_TYPE_INFO, tti2.getTypeAt(4));
Assert.assertEquals(BasicTypeInfo.STRING_TYPE_INFO, tti2.getTypeAt(5));
Assert.assertEquals(BasicTypeInfo.CHAR_TYPE_INFO, tti2.getTypeAt(6));
Assert.assertEquals(BasicTypeInfo.SHORT_TYPE_INFO, tti2.getTypeAt(7));
Assert.assertEquals(BasicTypeInfo.BYTE_TYPE_INFO, tti2.getTypeAt(8));
// test that getForClass does not work
try {
TypeExtractor.getForClass(Tuple9.class);
Assert.fail("Exception expected here");
} catch (InvalidTypesException e) {
// that is correct
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testTupleWithTuples() {
// use getFlatMapReturnTypes()
FlatMapFunction<?, ?> function = new FlatMapFunction<Tuple3<Tuple1<String>, Tuple1<Integer>, Tuple2<Long, Long>>, Tuple3<Tuple1<String>, Tuple1<Integer>, Tuple2<Long, Long>>>() {
private static final long serialVersionUID = 1L;
@Override
public void flatMap(Tuple3<Tuple1<String>, Tuple1<Integer>, Tuple2<Long, Long>> value,
Collector<Tuple3<Tuple1<String>, Tuple1<Integer>, Tuple2<Long, Long>>> out) throws Exception {
// nothing to do
}
};
TypeInformation<?> ti = TypeExtractor.getFlatMapReturnTypes(function, (TypeInformation) TypeInfoParser.parse("Tuple3<Tuple1<String>, Tuple1<Integer>, Tuple2<Long, Long>>"));
Assert.assertTrue(ti.isTupleType());
Assert.assertEquals(3, ti.getArity());
Assert.assertTrue(ti instanceof TupleTypeInfo);
TupleTypeInfo<?> tti = (TupleTypeInfo<?>) ti;
Assert.assertEquals(Tuple3.class, tti.getTypeClass());
Assert.assertTrue(tti.getTypeAt(0).isTupleType());
Assert.assertTrue(tti.getTypeAt(1).isTupleType());
Assert.assertTrue(tti.getTypeAt(2).isTupleType());
Assert.assertEquals(Tuple1.class, tti.getTypeAt(0).getTypeClass());
Assert.assertEquals(Tuple1.class, tti.getTypeAt(1).getTypeClass());
Assert.assertEquals(Tuple2.class, tti.getTypeAt(2).getTypeClass());
Assert.assertEquals(1, tti.getTypeAt(0).getArity());
Assert.assertEquals(1, tti.getTypeAt(1).getArity());
Assert.assertEquals(2, tti.getTypeAt(2).getArity());
Assert.assertEquals(BasicTypeInfo.STRING_TYPE_INFO, ((TupleTypeInfo<?>) tti.getTypeAt(0)).getTypeAt(0));
Assert.assertEquals(BasicTypeInfo.INT_TYPE_INFO, ((TupleTypeInfo<?>) tti.getTypeAt(1)).getTypeAt(0));
Assert.assertEquals(BasicTypeInfo.LONG_TYPE_INFO, ((TupleTypeInfo<?>) tti.getTypeAt(2)).getTypeAt(0));
Assert.assertEquals(BasicTypeInfo.LONG_TYPE_INFO, ((TupleTypeInfo<?>) tti.getTypeAt(2)).getTypeAt(1));
// use getForObject()
Tuple3<Tuple1<String>, Tuple1<Integer>, Tuple2<Long, Long>> t = new Tuple3<Tuple1<String>, Tuple1<Integer>, Tuple2<Long, Long>>(
new Tuple1<String>("hello"), new Tuple1<Integer>(1), new Tuple2<Long, Long>(2L, 3L));
Assert.assertTrue(TypeExtractor.getForObject(t) instanceof TupleTypeInfo);
TupleTypeInfo<?> tti2 = (TupleTypeInfo<?>) TypeExtractor.getForObject(t);
Assert.assertEquals(1, tti2.getTypeAt(0).getArity());
Assert.assertEquals(1, tti2.getTypeAt(1).getArity());
Assert.assertEquals(2, tti2.getTypeAt(2).getArity());
Assert.assertEquals(BasicTypeInfo.STRING_TYPE_INFO, ((TupleTypeInfo<?>) tti2.getTypeAt(0)).getTypeAt(0));
Assert.assertEquals(BasicTypeInfo.INT_TYPE_INFO, ((TupleTypeInfo<?>) tti2.getTypeAt(1)).getTypeAt(0));
Assert.assertEquals(BasicTypeInfo.LONG_TYPE_INFO, ((TupleTypeInfo<?>) tti2.getTypeAt(2)).getTypeAt(0));
Assert.assertEquals(BasicTypeInfo.LONG_TYPE_INFO, ((TupleTypeInfo<?>) tti2.getTypeAt(2)).getTypeAt(1));
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testSubclassOfTuple() {
// use getJoinReturnTypes()
JoinFunction<?, ?, ?> function = new JoinFunction<CustomTuple, String, CustomTuple>() {
private static final long serialVersionUID = 1L;
@Override
public CustomTuple join(CustomTuple first, String second) throws Exception {
return null;
}
};
TypeInformation<?> ti = TypeExtractor.getJoinReturnTypes(function, (TypeInformation) TypeInfoParser.parse("Tuple2<String, Integer>"), (TypeInformation) TypeInfoParser.parse("String"));
Assert.assertTrue(ti.isTupleType());
Assert.assertEquals(2, ti.getArity());
Assert.assertEquals(BasicTypeInfo.STRING_TYPE_INFO, ((TupleTypeInfo<?>) ti).getTypeAt(0));
Assert.assertEquals(BasicTypeInfo.INT_TYPE_INFO, ((TupleTypeInfo<?>) ti).getTypeAt(1));
Assert.assertEquals(CustomTuple.class, ((TupleTypeInfo<?>) ti).getTypeClass());
// use getForObject()
CustomTuple t = new CustomTuple("hello", 1);
TypeInformation<?> ti2 = TypeExtractor.getForObject(t);
Assert.assertTrue(ti2.isTupleType());
Assert.assertEquals(2, ti2.getArity());
Assert.assertEquals(BasicTypeInfo.STRING_TYPE_INFO, ((TupleTypeInfo<?>) ti2).getTypeAt(0));
Assert.assertEquals(BasicTypeInfo.INT_TYPE_INFO, ((TupleTypeInfo<?>) ti2).getTypeAt(1));
Assert.assertEquals(CustomTuple.class, ((TupleTypeInfo<?>) ti2).getTypeClass());
}
public static class CustomTuple extends Tuple2<String, Integer> {
private static final long serialVersionUID = 1L;
public CustomTuple(String myField1, Integer myField2) {
this.setFields(myField1, myField2);
}
public String getMyField1() {
return this.f0;
}
public int getMyField2() {
return this.f1;
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testCustomType() {
// use getCrossReturnTypes()
CrossFunction<?, ?, ?> function = new CrossFunction<CustomType, Integer, CustomType>() {
private static final long serialVersionUID = 1L;
@Override
public CustomType cross(CustomType first, Integer second) throws Exception {
return null;
}
};
TypeInformation<?> ti = TypeExtractor.getCrossReturnTypes(function, (TypeInformation) TypeInfoParser.parse("eu.stratosphere.api.java.type.extractor.TypeExtractorTest$CustomType"), (TypeInformation) TypeInfoParser.parse("Integer"));
Assert.assertFalse(ti.isBasicType());
Assert.assertFalse(ti.isTupleType());
Assert.assertTrue(ti instanceof GenericTypeInfo);
Assert.assertEquals(ti.getTypeClass(), CustomType.class);
// use getForClass()
Assert.assertTrue(TypeExtractor.getForClass(CustomType.class) instanceof GenericTypeInfo);
Assert.assertEquals(TypeExtractor.getForClass(CustomType.class).getTypeClass(), ti.getTypeClass());
// use getForObject()
CustomType t = new CustomType("World", 1);
TypeInformation<?> ti2 = TypeExtractor.getForObject(t);
Assert.assertFalse(ti2.isBasicType());
Assert.assertFalse(ti2.isTupleType());
Assert.assertTrue(ti2 instanceof GenericTypeInfo);
Assert.assertEquals(ti2.getTypeClass(), CustomType.class);
}
public static class CustomType {
public String myField1;
public int myField2;
public CustomType() {
}
public CustomType(String myField1, int myField2) {
this.myField1 = myField1;
this.myField2 = myField2;
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testTupleWithCustomType() {
// use getMapReturnTypes()
MapFunction<?, ?> function = new MapFunction<Tuple2<Long, CustomType>, Tuple2<Long, CustomType>>() {
private static final long serialVersionUID = 1L;
@Override
public Tuple2<Long, CustomType> map(Tuple2<Long, CustomType> value) throws Exception {
return null;
}
};
TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(function, (TypeInformation) TypeInfoParser.parse("Tuple2<Long,eu.stratosphere.api.java.type.extractor.TypeExtractorTest$CustomType>"));
Assert.assertTrue(ti.isTupleType());
Assert.assertEquals(2, ti.getArity());
TupleTypeInfo<?> tti = (TupleTypeInfo<?>) ti;
Assert.assertEquals(Tuple2.class, tti.getTypeClass());
Assert.assertEquals(Long.class, tti.getTypeAt(0).getTypeClass());
Assert.assertTrue(tti.getTypeAt(1) instanceof GenericTypeInfo);
Assert.assertEquals(CustomType.class, tti.getTypeAt(1).getTypeClass());
// use getForObject()
Tuple2<?, ?> t = new Tuple2<Long, CustomType>(1L, new CustomType("Hello", 1));
TypeInformation<?> ti2 = TypeExtractor.getForObject(t);
Assert.assertTrue(ti2.isTupleType());
Assert.assertEquals(2, ti2.getArity());
TupleTypeInfo<?> tti2 = (TupleTypeInfo<?>) ti2;
Assert.assertEquals(Tuple2.class, tti2.getTypeClass());
Assert.assertEquals(Long.class, tti2.getTypeAt(0).getTypeClass());
Assert.assertTrue(tti2.getTypeAt(1) instanceof GenericTypeInfo);
Assert.assertEquals(CustomType.class, tti2.getTypeAt(1).getTypeClass());
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testValue() {
// use getKeyExtractorType()
KeySelector<?, ?> function = new KeySelector<StringValue, StringValue>() {
private static final long serialVersionUID = 1L;
@Override
public StringValue getKey(StringValue value) {
return null;
}
};
TypeInformation<?> ti = TypeExtractor.getKeySelectorTypes(function, (TypeInformation) TypeInfoParser.parse("StringValue"));
Assert.assertFalse(ti.isBasicType());
Assert.assertFalse(ti.isTupleType());
Assert.assertTrue(ti instanceof ValueTypeInfo);
Assert.assertEquals(ti.getTypeClass(), StringValue.class);
// use getForClass()
Assert.assertTrue(TypeExtractor.getForClass(StringValue.class) instanceof ValueTypeInfo);
Assert.assertEquals(TypeExtractor.getForClass(StringValue.class).getTypeClass(), ti.getTypeClass());
// use getForObject()
StringValue v = new StringValue("Hello");
Assert.assertTrue(TypeExtractor.getForObject(v) instanceof ValueTypeInfo);
Assert.assertEquals(TypeExtractor.getForObject(v).getTypeClass(), ti.getTypeClass());
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testTupleOfValues() {
// use getMapReturnTypes()
MapFunction<?, ?> function = new MapFunction<Tuple2<StringValue, IntValue>, Tuple2<StringValue, IntValue>>() {
private static final long serialVersionUID = 1L;
@Override
public Tuple2<StringValue, IntValue> map(Tuple2<StringValue, IntValue> value) throws Exception {
return null;
}
};
TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(function, (TypeInformation) TypeInfoParser.parse("Tuple2<StringValue, IntValue>"));
Assert.assertFalse(ti.isBasicType());
Assert.assertTrue(ti.isTupleType());
Assert.assertEquals(StringValue.class, ((TupleTypeInfo<?>) ti).getTypeAt(0).getTypeClass());
Assert.assertEquals(IntValue.class, ((TupleTypeInfo<?>) ti).getTypeAt(1).getTypeClass());
// use getForObject()
Tuple2<StringValue, IntValue> t = new Tuple2<StringValue, IntValue>(new StringValue("x"), new IntValue(1));
TypeInformation<?> ti2 = TypeExtractor.getForObject(t);
Assert.assertFalse(ti2.isBasicType());
Assert.assertTrue(ti2.isTupleType());
Assert.assertEquals(((TupleTypeInfo<?>) ti2).getTypeAt(0).getTypeClass(), StringValue.class);
Assert.assertEquals(((TupleTypeInfo<?>) ti2).getTypeAt(1).getTypeClass(), IntValue.class);
}
public static class LongKeyValue<V> extends Tuple2<Long, V> {
private static final long serialVersionUID = 1L;
public LongKeyValue(Long field1, V field2) {
this.f0 = field1;
this.f1 = field2;
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testGenericsNotInSuperclass() {
// use getMapReturnTypes()
MapFunction<?, ?> function = new MapFunction<LongKeyValue<String>, LongKeyValue<String>>() {
private static final long serialVersionUID = 1L;
@Override
public LongKeyValue<String> map(LongKeyValue<String> value) throws Exception {
return null;
}
};
TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(function, (TypeInformation) TypeInfoParser.parse("Tuple2<Long, String>"));
Assert.assertTrue(ti.isTupleType());
Assert.assertEquals(2, ti.getArity());
TupleTypeInfo<?> tti = (TupleTypeInfo<?>) ti;
Assert.assertEquals(LongKeyValue.class, tti.getTypeClass());
Assert.assertEquals(BasicTypeInfo.LONG_TYPE_INFO, tti.getTypeAt(0));
Assert.assertEquals(BasicTypeInfo.STRING_TYPE_INFO, tti.getTypeAt(1));
}
public static class ChainedOne<X, Y> extends Tuple3<X, Long, Y> {
private static final long serialVersionUID = 1L;
public ChainedOne(X field0, Long field1, Y field2) {
this.f0 = field0;
this.f1 = field1;
this.f2 = field2;
}
}
public static class ChainedTwo<V> extends ChainedOne<String, V> {
private static final long serialVersionUID = 1L;
public ChainedTwo(String field0, Long field1, V field2) {
super(field0, field1, field2);
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testChainedGenericsNotInSuperclass() {
// use TypeExtractor
MapFunction<?, ?> function = new MapFunction<ChainedTwo<Integer>, ChainedTwo<Integer>>() {
private static final long serialVersionUID = 1L;
@Override
public ChainedTwo<Integer> map(ChainedTwo<Integer> value) throws Exception {
return null;
}
};
TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(function, (TypeInformation) TypeInfoParser.parse("Tuple3<String, Long, Integer>"));
Assert.assertTrue(ti.isTupleType());
Assert.assertEquals(3, ti.getArity());
TupleTypeInfo<?> tti = (TupleTypeInfo<?>) ti;
Assert.assertEquals(ChainedTwo.class, tti.getTypeClass());
Assert.assertEquals(BasicTypeInfo.STRING_TYPE_INFO, tti.getTypeAt(0));
Assert.assertEquals(BasicTypeInfo.LONG_TYPE_INFO, tti.getTypeAt(1));
Assert.assertEquals(BasicTypeInfo.INT_TYPE_INFO, tti.getTypeAt(2));
}
public static class ChainedThree extends ChainedTwo<String> {
private static final long serialVersionUID = 1L;
public ChainedThree(String field0, Long field1, String field2) {
super(field0, field1, field2);
}
}
public static class ChainedFour extends ChainedThree {
private static final long serialVersionUID = 1L;
public ChainedFour(String field0, Long field1, String field2) {
super(field0, field1, field2);
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testGenericsInDirectSuperclass() {
// use TypeExtractor
MapFunction<?, ?> function = new MapFunction<ChainedThree, ChainedThree>() {
private static final long serialVersionUID = 1L;
@Override
public ChainedThree map(ChainedThree value) throws Exception {
return null;
}
};
TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(function, (TypeInformation) TypeInfoParser.parse("Tuple3<String, Long, String>"));
Assert.assertTrue(ti.isTupleType());
Assert.assertEquals(3, ti.getArity());
TupleTypeInfo<?> tti = (TupleTypeInfo<?>) ti;
Assert.assertEquals(ChainedThree.class, tti.getTypeClass());
Assert.assertEquals(BasicTypeInfo.STRING_TYPE_INFO, tti.getTypeAt(0));
Assert.assertEquals(BasicTypeInfo.LONG_TYPE_INFO, tti.getTypeAt(1));
Assert.assertEquals(BasicTypeInfo.STRING_TYPE_INFO, tti.getTypeAt(2));
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testGenericsNotInSuperclassWithNonGenericClassAtEnd() {
// use TypeExtractor
MapFunction<?, ?> function = new MapFunction<ChainedFour, ChainedFour>() {
private static final long serialVersionUID = 1L;
@Override
public ChainedFour map(ChainedFour value) throws Exception {
return null;
}
};
TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(function, (TypeInformation) TypeInfoParser.parse("Tuple3<String, Long, String>"));
Assert.assertTrue(ti.isTupleType());
Assert.assertEquals(3, ti.getArity());
TupleTypeInfo<?> tti = (TupleTypeInfo<?>) ti;
Assert.assertEquals(ChainedFour.class, tti.getTypeClass());
Assert.assertEquals(BasicTypeInfo.STRING_TYPE_INFO, tti.getTypeAt(0));
Assert.assertEquals(BasicTypeInfo.LONG_TYPE_INFO, tti.getTypeAt(1));
Assert.assertEquals(BasicTypeInfo.STRING_TYPE_INFO, tti.getTypeAt(2));
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testMissingTupleGenericsException() {
MapFunction<?, ?> function = new MapFunction<String, Tuple2>() {
private static final long serialVersionUID = 1L;
@Override
public Tuple2 map(String value) throws Exception {
return null;
}
};
try {
TypeExtractor.getMapReturnTypes(function, (TypeInformation) TypeInfoParser.parse("String"));
Assert.fail("exception expected");
} catch (InvalidTypesException e) {
// right
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testTupleSupertype() {
MapFunction<?, ?> function = new MapFunction<String, Tuple>() {
private static final long serialVersionUID = 1L;
@Override
public Tuple map(String value) throws Exception {
return null;
}
};
try {
TypeExtractor.getMapReturnTypes(function, (TypeInformation) TypeInfoParser.parse("String"));
Assert.fail("exception expected");
} catch (InvalidTypesException e) {
// right
}
}
public static class SameTypeVariable<X> extends Tuple2<X, X> {
private static final long serialVersionUID = 1L;
public SameTypeVariable(X field0, X field1) {
super(field0, field1);
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testSameGenericVariable() {
MapFunction<?, ?> function = new MapFunction<SameTypeVariable<String>, SameTypeVariable<String>>() {
private static final long serialVersionUID = 1L;
@Override
public SameTypeVariable<String> map(SameTypeVariable<String> value) throws Exception {
return null;
}
};
TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(function, (TypeInformation) TypeInfoParser.parse("Tuple2<String, String>"));
Assert.assertTrue(ti.isTupleType());
Assert.assertEquals(2, ti.getArity());
TupleTypeInfo<?> tti = (TupleTypeInfo<?>) ti;
Assert.assertEquals(SameTypeVariable.class, tti.getTypeClass());
Assert.assertEquals(BasicTypeInfo.STRING_TYPE_INFO, tti.getTypeAt(0));
Assert.assertEquals(BasicTypeInfo.STRING_TYPE_INFO, tti.getTypeAt(1));
}
public static class Nested<V, T> extends Tuple2<V, Tuple2<T, T>> {
private static final long serialVersionUID = 1L;
public Nested(V field0, Tuple2<T, T> field1) {
super(field0, field1);
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testNestedTupleGenerics() {
MapFunction<?, ?> function = new MapFunction<Nested<String, Integer>, Nested<String, Integer>>() {
private static final long serialVersionUID = 1L;
@Override
public Nested<String, Integer> map(Nested<String, Integer> value) throws Exception {
return null;
}
};
TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(function, (TypeInformation) TypeInfoParser.parse("Tuple2<String, Tuple2<Integer, Integer>>"));
Assert.assertTrue(ti.isTupleType());
Assert.assertEquals(2, ti.getArity());
TupleTypeInfo<?> tti = (TupleTypeInfo<?>) ti;
Assert.assertEquals(Nested.class, tti.getTypeClass());
Assert.assertEquals(BasicTypeInfo.STRING_TYPE_INFO, tti.getTypeAt(0));
Assert.assertTrue(tti.getTypeAt(1).isTupleType());
Assert.assertEquals(2, tti.getTypeAt(1).getArity());
// Nested
TupleTypeInfo<?> tti2 = (TupleTypeInfo<?>) tti.getTypeAt(1);
Assert.assertEquals(Tuple2.class, tti2.getTypeClass());
Assert.assertEquals(BasicTypeInfo.INT_TYPE_INFO, tti2.getTypeAt(0));
Assert.assertEquals(BasicTypeInfo.INT_TYPE_INFO, tti2.getTypeAt(1));
}
public static class Nested2<T> extends Nested<T, Nested<Integer, T>> {
private static final long serialVersionUID = 1L;
public Nested2(T field0, Tuple2<Nested<Integer, T>, Nested<Integer, T>> field1) {
super(field0, field1);
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testNestedTupleGenerics2() {
MapFunction<?, ?> function = new MapFunction<Nested2<Boolean>, Nested2<Boolean>>() {
private static final long serialVersionUID = 1L;
@Override
public Nested2<Boolean> map(Nested2<Boolean> value) throws Exception {
return null;
}
};
TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(function, (TypeInformation) TypeInfoParser.parse("Tuple2<Boolean, Tuple2<Tuple2<Integer, Tuple2<Boolean, Boolean>>, Tuple2<Integer, Tuple2<Boolean, Boolean>>>>"));
// Should be
// Tuple2<Boolean, Tuple2<Tuple2<Integer, Tuple2<Boolean, Boolean>>, Tuple2<Integer, Tuple2<Boolean, Boolean>>>>
// 1st nested level
Assert.assertTrue(ti.isTupleType());
Assert.assertEquals(2, ti.getArity());
TupleTypeInfo<?> tti = (TupleTypeInfo<?>) ti;
Assert.assertEquals(BasicTypeInfo.BOOLEAN_TYPE_INFO, tti.getTypeAt(0));
Assert.assertTrue(tti.getTypeAt(1).isTupleType());
// 2nd nested level
TupleTypeInfo<?> tti2 = (TupleTypeInfo<?>) tti.getTypeAt(1);
Assert.assertTrue(tti2.getTypeAt(0).isTupleType());
Assert.assertTrue(tti2.getTypeAt(1).isTupleType());
// 3rd nested level
TupleTypeInfo<?> tti3 = (TupleTypeInfo<?>) tti2.getTypeAt(0);
Assert.assertEquals(BasicTypeInfo.INT_TYPE_INFO, tti3.getTypeAt(0));
Assert.assertTrue(tti3.getTypeAt(1).isTupleType());
// 4th nested level
TupleTypeInfo<?> tti4 = (TupleTypeInfo<?>) tti3.getTypeAt(1);
Assert.assertEquals(BasicTypeInfo.BOOLEAN_TYPE_INFO, tti4.getTypeAt(0));
Assert.assertEquals(BasicTypeInfo.BOOLEAN_TYPE_INFO, tti4.getTypeAt(1));
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testFunctionWithMissingGenerics() {
MapFunction function = new MapFunction() {
private static final long serialVersionUID = 1L;
@Override
public String map(Object value) throws Exception {
return null;
}
};
try {
TypeExtractor.getMapReturnTypes(function, TypeInfoParser.parse("String"));
Assert.fail("exception expected");
} catch (InvalidTypesException e) {
// right
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void testFunctionDependingOnInputAsSuperclass() {
IdentityMapper<Boolean> function = new IdentityMapper<Boolean>() {
private static final long serialVersionUID = 1L;
};
TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(function, (TypeInformation) TypeInfoParser.parse("Boolean"));
Assert.assertTrue(ti.isBasicType());
Assert.assertEquals(BasicTypeInfo.BOOLEAN_TYPE_INFO, ti);
}
public class IdentityMapper<T> extends MapFunction<T, T> {
private static final long serialVersionUID = 1L;
@Override
public T map(T value) throws Exception {
return null;
}
}
@Test
public void testFunctionDependingOnInputFromInput() {
IdentityMapper<Boolean> function = new IdentityMapper<Boolean>();
TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(function, BasicTypeInfo.BOOLEAN_TYPE_INFO);
Assert.assertTrue(ti.isBasicType());
Assert.assertEquals(BasicTypeInfo.BOOLEAN_TYPE_INFO, ti);
}
@Test
public void testFunctionDependingOnInputWithMissingInput() {
IdentityMapper<Boolean> function = new IdentityMapper<Boolean>();
try {
TypeExtractor.getMapReturnTypes(function, null);
Assert.fail("exception expected");
} catch (InvalidTypesException e) {
// right
}
}
public class IdentityMapper2<T> extends MapFunction<Tuple2<T, String>, T> {
private static final long serialVersionUID = 1L;
@Override
public T map(Tuple2<T, String> value) throws Exception {
return null;
}
}
@Test
public void testFunctionDependingOnInputWithTupleInput() {
IdentityMapper2<Boolean> function = new IdentityMapper2<Boolean>();
TypeInformation<Tuple2<Boolean, String>> inputType = new TupleTypeInfo<Tuple2<Boolean, String>>(BasicTypeInfo.BOOLEAN_TYPE_INFO,
BasicTypeInfo.STRING_TYPE_INFO);
TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(function, inputType);
Assert.assertTrue(ti.isBasicType());
Assert.assertEquals(BasicTypeInfo.BOOLEAN_TYPE_INFO, ti);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void testFunctionDependingOnInputWithCustomTupleInput() {
IdentityMapper<SameTypeVariable<String>> function = new IdentityMapper<SameTypeVariable<String>>();
TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(function, (TypeInformation) TypeInfoParser.parse("Tuple2<String, String>"));
Assert.assertTrue(ti.isTupleType());
Assert.assertEquals(2, ti.getArity());
TupleTypeInfo<?> tti = (TupleTypeInfo<?>) ti;
Assert.assertEquals(BasicTypeInfo.STRING_TYPE_INFO, tti.getTypeAt(0));
Assert.assertEquals(BasicTypeInfo.STRING_TYPE_INFO, tti.getTypeAt(1));
}
public class IdentityMapper3<T, V> extends MapFunction<T, V> {
private static final long serialVersionUID = 1L;
@Override
public V map(T value) throws Exception {
return null;
}
}
@Test
public void testFunctionDependingOnInputException() {
IdentityMapper3<Boolean, String> function = new IdentityMapper3<Boolean, String>();
try {
TypeExtractor.getMapReturnTypes(function, BasicTypeInfo.BOOLEAN_TYPE_INFO);
Assert.fail("exception expected");
} catch (InvalidTypesException e) {
// right
}
}
public class IdentityMapper4<D> extends IdentityMapper<D> {
private static final long serialVersionUID = 1L;
}
@Test
public void testFunctionDependingOnInputWithFunctionHierarchy() {
IdentityMapper4<String> function = new IdentityMapper4<String>();
TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(function, BasicTypeInfo.STRING_TYPE_INFO);
Assert.assertEquals(BasicTypeInfo.STRING_TYPE_INFO, ti);
}
public class IdentityMapper5<D> extends IdentityMapper<Tuple2<D, D>> {
private static final long serialVersionUID = 1L;
}
@Test
public void testFunctionDependingOnInputWithFunctionHierarchy2() {
IdentityMapper5<String> function = new IdentityMapper5<String>();
@SuppressWarnings({ "rawtypes", "unchecked" })
TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(function, new TupleTypeInfo(BasicTypeInfo.STRING_TYPE_INFO,
BasicTypeInfo.STRING_TYPE_INFO));
Assert.assertTrue(ti.isTupleType());
TupleTypeInfo<?> tti = (TupleTypeInfo<?>) ti;
Assert.assertEquals(BasicTypeInfo.STRING_TYPE_INFO, tti.getTypeAt(0));
Assert.assertEquals(BasicTypeInfo.STRING_TYPE_INFO, tti.getTypeAt(1));
}
public class Mapper extends IdentityMapper<String> {
private static final long serialVersionUID = 1L;
@Override
public String map(String value) throws Exception {
return null;
}
}
public class Mapper2 extends Mapper {
private static final long serialVersionUID = 1L;
@Override
public String map(String value) throws Exception {
return null;
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void testFunctionWithNoGenericSuperclass() {
MapFunction<?, ?> function = new Mapper2();
TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(function, (TypeInformation) TypeInfoParser.parse("String"));
Assert.assertTrue(ti.isBasicType());
Assert.assertEquals(BasicTypeInfo.STRING_TYPE_INFO, ti);
}
public class OneAppender<T> extends MapFunction<T, Tuple2<T, Integer>> {
private static final long serialVersionUID = 1L;
public Tuple2<T, Integer> map(T value) {
return new Tuple2<T, Integer>(value, 1);
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void testFunctionDependingPartialOnInput() {
MapFunction<?, ?> function = new OneAppender<DoubleValue>() {
private static final long serialVersionUID = 1L;
};
TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(function, (TypeInformation) TypeInfoParser.parse("DoubleValue"));
Assert.assertTrue(ti.isTupleType());
Assert.assertEquals(2, ti.getArity());
TupleTypeInfo<?> tti = (TupleTypeInfo<?>) ti;
Assert.assertTrue(tti.getTypeAt(0) instanceof ValueTypeInfo<?>);
ValueTypeInfo<?> vti = (ValueTypeInfo<?>) tti.getTypeAt(0);
Assert.assertEquals(DoubleValue.class, vti.getTypeClass());
Assert.assertTrue(tti.getTypeAt(1).isBasicType());
Assert.assertEquals(Integer.class , tti.getTypeAt(1).getTypeClass());
}
@Test
public void testFunctionDependingPartialOnInput2() {
MapFunction<DoubleValue, ?> function = new OneAppender<DoubleValue>();
TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(function, new ValueTypeInfo<DoubleValue>(DoubleValue.class));
Assert.assertTrue(ti.isTupleType());
Assert.assertEquals(2, ti.getArity());
TupleTypeInfo<?> tti = (TupleTypeInfo<?>) ti;
Assert.assertTrue(tti.getTypeAt(0) instanceof ValueTypeInfo<?>);
ValueTypeInfo<?> vti = (ValueTypeInfo<?>) tti.getTypeAt(0);
Assert.assertEquals(DoubleValue.class, vti.getTypeClass());
Assert.assertTrue(tti.getTypeAt(1).isBasicType());
Assert.assertEquals(Integer.class , tti.getTypeAt(1).getTypeClass());
}
public class FieldDuplicator<T> extends MapFunction<T, Tuple2<T, T>> {
private static final long serialVersionUID = 1L;
public Tuple2<T, T> map(T value) {
return new Tuple2<T, T>(value, value);
}
}
@Test
public void testFunctionInputInOutputMultipleTimes() {
MapFunction<Float, ?> function = new FieldDuplicator<Float>();
TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(function, BasicTypeInfo.FLOAT_TYPE_INFO);
Assert.assertTrue(ti.isTupleType());
Assert.assertEquals(2, ti.getArity());
TupleTypeInfo<?> tti = (TupleTypeInfo<?>) ti;
Assert.assertEquals(BasicTypeInfo.FLOAT_TYPE_INFO, tti.getTypeAt(0));
Assert.assertEquals(BasicTypeInfo.FLOAT_TYPE_INFO, tti.getTypeAt(1));
}
@Test
public void testFunctionInputInOutputMultipleTimes2() {
MapFunction<Tuple2<Float, Float>, ?> function = new FieldDuplicator<Tuple2<Float, Float>>();
TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(function, new TupleTypeInfo<Tuple2<Float, Float>>(
BasicTypeInfo.FLOAT_TYPE_INFO, BasicTypeInfo.FLOAT_TYPE_INFO));
// should be
// Tuple2<Tuple2<Float, Float>, Tuple2<Float, Float>>
Assert.assertTrue(ti.isTupleType());
Assert.assertEquals(2, ti.getArity());
TupleTypeInfo<?> tti = (TupleTypeInfo<?>) ti;
// 2nd nested level
Assert.assertTrue(tti.getTypeAt(0).isTupleType());
TupleTypeInfo<?> tti2 = (TupleTypeInfo<?>) tti.getTypeAt(0);
Assert.assertEquals(BasicTypeInfo.FLOAT_TYPE_INFO, tti2.getTypeAt(0));
Assert.assertEquals(BasicTypeInfo.FLOAT_TYPE_INFO, tti2.getTypeAt(1));
Assert.assertTrue(tti.getTypeAt(0).isTupleType());
TupleTypeInfo<?> tti3 = (TupleTypeInfo<?>) tti.getTypeAt(1);
Assert.assertEquals(BasicTypeInfo.FLOAT_TYPE_INFO, tti3.getTypeAt(0));
Assert.assertEquals(BasicTypeInfo.FLOAT_TYPE_INFO, tti3.getTypeAt(1));
}
public interface Testable {}
public abstract class AbstractClass {}
@Test
public void testAbstractAndInterfaceTypesException() {
MapFunction<String, ?> function = new MapFunction<String, Testable>() {
private static final long serialVersionUID = 1L;
@Override
public Testable map(String value) throws Exception {
return null;
}
};
try {
TypeExtractor.getMapReturnTypes(function, BasicTypeInfo.STRING_TYPE_INFO);
Assert.fail("exception expected");
} catch (InvalidTypesException e) {
// good
}
MapFunction<String, ?> function2 = new MapFunction<String, AbstractClass>() {
private static final long serialVersionUID = 1L;
@Override
public AbstractClass map(String value) throws Exception {
return null;
}
};
try {
TypeExtractor.getMapReturnTypes(function2, BasicTypeInfo.STRING_TYPE_INFO);
Assert.fail("exception expected");
} catch (InvalidTypesException e) {
// slick!
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void testValueSupertypeException() {
MapFunction<?, ?> function = new MapFunction<StringValue, Value>() {
private static final long serialVersionUID = 1L;
@Override
public Value map(StringValue value) throws Exception {
return null;
}
};
try {
TypeExtractor.getMapReturnTypes(function, (TypeInformation)TypeInfoParser.parse("StringValue"));
Assert.fail("exception expected");
} catch (InvalidTypesException e) {
// bam! go type extractor!
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void testBasicArray() {
// use getCoGroupReturnTypes()
CoGroupFunction<?, ?, ?> function = new CoGroupFunction<String[], String[], String[]>() {
private static final long serialVersionUID = 1L;
@Override
public void coGroup(Iterator<String[]> first, Iterator<String[]> second, Collector<String[]> out) throws Exception {
// nothing to do
}
};
TypeInformation<?> ti = TypeExtractor.getCoGroupReturnTypes(function, (TypeInformation) TypeInfoParser.parse("String[]"), (TypeInformation) TypeInfoParser.parse("String[]"));
Assert.assertFalse(ti.isBasicType());
Assert.assertFalse(ti.isTupleType());
// Due to a Java 6 bug the classification can be slightly wrong
Assert.assertTrue(ti instanceof BasicArrayTypeInfo<?,?> || ti instanceof ObjectArrayTypeInfo<?,?>);
if(ti instanceof BasicArrayTypeInfo<?,?>) {
Assert.assertEquals(BasicArrayTypeInfo.STRING_ARRAY_TYPE_INFO, ti);
}
else {
Assert.assertEquals(BasicTypeInfo.STRING_TYPE_INFO, ((ObjectArrayTypeInfo<?,?>) ti).getComponentInfo());
}
}
@Test
public void testBasicArray2() {
MapFunction<Boolean[], ?> function = new IdentityMapper<Boolean[]>();
TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(function, BasicArrayTypeInfo.BOOLEAN_ARRAY_TYPE_INFO);
Assert.assertTrue(ti instanceof BasicArrayTypeInfo<?, ?>);
BasicArrayTypeInfo<?, ?> bati = (BasicArrayTypeInfo<?, ?>) ti;
Assert.assertTrue(bati.getComponentInfo().isBasicType());
Assert.assertEquals(BasicTypeInfo.BOOLEAN_TYPE_INFO, bati.getComponentInfo());
}
public static class CustomArrayObject {}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void testCustomArray() {
MapFunction<?, ?> function = new MapFunction<CustomArrayObject[], CustomArrayObject[]>() {
private static final long serialVersionUID = 1L;
@Override
public CustomArrayObject[] map(CustomArrayObject[] value) throws Exception {
return null;
}
};
TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(function, (TypeInformation) TypeInfoParser.parse("eu.stratosphere.api.java.type.extractor.TypeExtractorTest$CustomArrayObject[]"));
Assert.assertTrue(ti instanceof ObjectArrayTypeInfo<?, ?>);
Assert.assertEquals(CustomArrayObject.class, ((ObjectArrayTypeInfo<?, ?>) ti).getComponentType());
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void testTupleArray() {
MapFunction<?, ?> function = new MapFunction<Tuple2<String, String>[], Tuple2<String, String>[]>() {
private static final long serialVersionUID = 1L;
@Override
public Tuple2<String, String>[] map(Tuple2<String, String>[] value) throws Exception {
return null;
}
};
TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(function, (TypeInformation) TypeInfoParser.parse("Tuple2<String, String>[]"));
Assert.assertTrue(ti instanceof ObjectArrayTypeInfo<?, ?>);
ObjectArrayTypeInfo<?, ?> oati = (ObjectArrayTypeInfo<?, ?>) ti;
Assert.assertTrue(oati.getComponentInfo().isTupleType());
TupleTypeInfo<?> tti = (TupleTypeInfo<?>) oati.getComponentInfo();
Assert.assertEquals(BasicTypeInfo.STRING_TYPE_INFO, tti.getTypeAt(0));
Assert.assertEquals(BasicTypeInfo.STRING_TYPE_INFO, tti.getTypeAt(1));
}
public class CustomArrayObject2<F> extends Tuple1<F> {
private static final long serialVersionUID = 1L;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void testCustomArrayWithTypeVariable() {
MapFunction<CustomArrayObject2<Boolean>[], ?> function = new IdentityMapper<CustomArrayObject2<Boolean>[]>();
TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(function, (TypeInformation) TypeInfoParser.parse("Tuple1<Boolean>[]"));
Assert.assertTrue(ti instanceof ObjectArrayTypeInfo<?, ?>);
ObjectArrayTypeInfo<?, ?> oati = (ObjectArrayTypeInfo<?, ?>) ti;
Assert.assertTrue(oati.getComponentInfo().isTupleType());
TupleTypeInfo<?> tti = (TupleTypeInfo<?>) oati.getComponentInfo();
Assert.assertEquals(BasicTypeInfo.BOOLEAN_TYPE_INFO, tti.getTypeAt(0));
}
public class GenericArrayClass<T> extends MapFunction<T[], T[]> {
private static final long serialVersionUID = 1L;
@Override
public T[] map(T[] value) throws Exception {
return null;
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void testParameterizedArrays() {
GenericArrayClass<Boolean> function = new GenericArrayClass<Boolean>(){
private static final long serialVersionUID = 1L;
};
TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(function, (TypeInformation) TypeInfoParser.parse("Boolean[]"));
Assert.assertTrue(ti instanceof ObjectArrayTypeInfo<?,?>);
ObjectArrayTypeInfo<?, ?> oati = (ObjectArrayTypeInfo<?, ?>) ti;
Assert.assertEquals(BasicTypeInfo.BOOLEAN_TYPE_INFO, oati.getComponentInfo());
}
public static class MyObject<T> {
public T myField;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void testParamertizedCustomObject() {
MapFunction<?, ?> function = new MapFunction<MyObject<String>, MyObject<String>>() {
private static final long serialVersionUID = 1L;
@Override
public MyObject<String> map(MyObject<String> value) throws Exception {
return null;
}
};
TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(function, (TypeInformation) TypeInfoParser.parse("eu.stratosphere.api.java.type.extractor.TypeExtractorTest$MyObject"));
Assert.assertTrue(ti instanceof GenericTypeInfo<?>);
}
@Test
public void testFunctionDependingOnInputWithTupleInputWithTypeMismatch() {
IdentityMapper2<Boolean> function = new IdentityMapper2<Boolean>();
TypeInformation<Tuple2<Boolean, String>> inputType = new TupleTypeInfo<Tuple2<Boolean, String>>(BasicTypeInfo.BOOLEAN_TYPE_INFO,
BasicTypeInfo.INT_TYPE_INFO);
// input is: Tuple2<Boolean, Integer>
// allowed: Tuple2<?, String>
try {
TypeExtractor.getMapReturnTypes(function, inputType);
Assert.fail("exception expected");
} catch (InvalidTypesException e) {
// right
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void testInputMismatchExceptions() {
MapFunction<?, ?> function = new MapFunction<Tuple2<String, String>, String>() {
private static final long serialVersionUID = 1L;
@Override
public String map(Tuple2<String, String> value) throws Exception {
return null;
}
};
try {
TypeExtractor.getMapReturnTypes(function, (TypeInformation) TypeInfoParser.parse("Tuple2<Integer, String>"));
Assert.fail("exception expected");
} catch (InvalidTypesException e) {
// right
}
try {
TypeExtractor.getMapReturnTypes(function, (TypeInformation) TypeInfoParser.parse("Tuple3<String, String, String>"));
Assert.fail("exception expected");
} catch (InvalidTypesException e) {
// right
}
MapFunction<?, ?> function2 = new MapFunction<StringValue, String>() {
private static final long serialVersionUID = 1L;
@Override
public String map(StringValue value) throws Exception {
return null;
}
};
try {
TypeExtractor.getMapReturnTypes(function2, (TypeInformation) TypeInfoParser.parse("IntValue"));
Assert.fail("exception expected");
} catch (InvalidTypesException e) {
// right
}
MapFunction<?, ?> function3 = new MapFunction<Tuple1<Integer>[], String>() {
private static final long serialVersionUID = 1L;
@Override
public String map(Tuple1<Integer>[] value) throws Exception {
return null;
}
};
try {
TypeExtractor.getMapReturnTypes(function3, (TypeInformation) TypeInfoParser.parse("Integer[]"));
Assert.fail("exception expected");
} catch (InvalidTypesException e) {
// right
}
MapFunction<?, ?> function4 = new MapFunction<Writable, String>() {
private static final long serialVersionUID = 1L;
@Override
public String map(Writable value) throws Exception {
return null;
}
};
try {
TypeExtractor.getMapReturnTypes(function4, (TypeInformation) new WritableTypeInfo<MyWritable>(MyWritable.class));
Assert.fail("exception expected");
} catch (InvalidTypesException e) {
// right
}
}
public static class DummyFlatMapFunction<A,B,C,D> extends FlatMapFunction<Tuple2<A,B>, Tuple2<C,D>> {
private static final long serialVersionUID = 1L;
@Override
public void flatMap(Tuple2<A, B> value, Collector<Tuple2<C, D>> out) throws Exception {
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testTypeErasureException() {
try {
TypeExtractor.getFlatMapReturnTypes(new DummyFlatMapFunction<String, Integer, String, Boolean>(),
(TypeInformation) TypeInfoParser.parse("Tuple2<String, Integer>"));
Assert.fail("exception expected");
}
catch (InvalidTypesException e) {
// right
}
}
public static class MyQueryableMapper<A> extends MapFunction<String, A> implements ResultTypeQueryable<A> {
private static final long serialVersionUID = 1L;
@SuppressWarnings("unchecked")
@Override
public TypeInformation<A> getProducedType() {
return (TypeInformation<A>) BasicTypeInfo.INT_TYPE_INFO;
}
@Override
public A map(String value) throws Exception {
return null;
}
}
@Test
public void testResultTypeQueryable() {
TypeInformation<?> ti = TypeExtractor.getMapReturnTypes(new MyQueryableMapper<Integer>(), BasicTypeInfo.STRING_TYPE_INFO);
Assert.assertEquals(BasicTypeInfo.INT_TYPE_INFO, ti);
}
}