/* * Copyright (C) 2014 The Android Open Source Project * * 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.android.mediaframeworktest.unit; import static android.hardware.camera2.utils.TypeReference.*; import android.hardware.camera2.utils.TypeReference; import android.test.suitebuilder.annotation.SmallTest; import android.util.Log; import java.lang.reflect.Type; import java.util.List; public class CameraUtilsTypeReferenceTest extends junit.framework.TestCase { private static final String TAG = CameraUtilsTypeReferenceTest.class.getSimpleName(); private static final boolean VERBOSE = false; private class RegularClass {} private class SubClass extends RegularClass {} private class GenericClass {} private class SubGenericClass extends GenericClass {} private class SpecificClass extends GenericClass {} private interface RegularInterface {} private interface GenericInterface {} private interface GenericInterface2 {} private class ImplementsRegularInterface implements RegularInterface {} private class ImplementsGenericInterface implements GenericInterface {} private class Implements2GenericInterface implements GenericInterface, GenericInterface2 {} private class GenericOuterClass { class GenericInnerClass { @SuppressWarnings("unused") T field; } } private static void assertContainsTypeVariable(Type type) { assertTrue(type.toString() + " was expected to have a type variable, but it didn't", containsTypeVariable(type)); } private static void assertLacksTypeVariable(Type type) { assertFalse(type.toString() + " was expected to *not* have a type variable, but it did", containsTypeVariable(type)); } /* * Only test classes and interfaces. Other types are not tested (e.g. fields, methods, etc). */ @SmallTest public void testLacksTypeVariables() { assertLacksTypeVariable(RegularClass.class); assertLacksTypeVariable(SubClass.class); assertLacksTypeVariable(SpecificClass.class); assertLacksTypeVariable(RegularInterface.class); assertLacksTypeVariable(ImplementsRegularInterface.class); } @SmallTest public void testContainsTypeVariables() { assertContainsTypeVariable(GenericClass.class); assertContainsTypeVariable(SubGenericClass.class); assertContainsTypeVariable(GenericInterface.class); assertContainsTypeVariable(ImplementsGenericInterface.class); assertContainsTypeVariable(Implements2GenericInterface.class); assertContainsTypeVariable(GenericOuterClass.class); assertContainsTypeVariable(GenericOuterClass.GenericInnerClass.class); } /** * This should always throw an IllegalArgumentException since the * type reference to {@code T} will contain a type variable (also {@code T}). * * @throws IllegalArgumentException unconditionally */ private static TypeReference createTypeRefWithTypeVar() { return new TypeReference() {{ }}; } @SmallTest public void testTypeReferences() { TypeReference typeRefInt = new TypeReference() {{ }}; TypeReference typeRefInt2 = new TypeReference() {{ }}; assertEquals(typeRefInt, typeRefInt2); assertEquals("The type ref's captured type should be the Integer class", Integer.class, typeRefInt.getType()); TypeReference typeRefFloat = new TypeReference() {{ }}; assertFalse("Integer/Float type references must not be equal", typeRefInt.equals(typeRefFloat)); assertEquals("The type ref's captured type should be the Float class", Float.class, typeRefFloat.getType()); try { TypeReference typeRefTypeVar = createTypeRefWithTypeVar(); fail("Expected a type reference with type variables to fail"); // Unreachable. Make the warning about an unused variable go away. assertFalse(typeRefTypeVar.equals(typeRefInt)); } catch (IllegalArgumentException e) { // OK. Expected behavior } } // Compare the raw type against rawClass private static void assertRawTypeEquals(TypeReference typeRef, Class rawClass) { assertEquals("Expected the raw type from " + typeRef + " to match the class " + rawClass, rawClass, typeRef.getRawType()); } // Compare the normal type against the klass private static void assertTypeReferenceEquals(TypeReference typeRef, Class klass) { assertEquals("Expected the type from " + typeRef + " to match the class " + klass, klass, typeRef.getType()); } @SmallTest public void testRawTypes() { TypeReference intToken = new TypeReference() {{ }}; assertRawTypeEquals(intToken, Integer.class); TypeReference> listToken = new TypeReference>() {{ }}; assertRawTypeEquals(listToken, List.class); TypeReference>> listListToken = new TypeReference>>() {{ }}; assertRawTypeEquals(listListToken, List.class); TypeReference intArrayToken = new TypeReference() {{ }}; assertRawTypeEquals(intArrayToken, int[].class); TypeReference integerArrayToken = new TypeReference() {{ }}; assertRawTypeEquals(integerArrayToken, Integer[].class); TypeReference[]> listArrayToken = new TypeReference[]>() {{ }}; assertRawTypeEquals(listArrayToken, List[].class); } private class IntTokenOne extends TypeReference {} private class IntTokenTwo extends TypeReference {} private class IntArrayToken1 extends TypeReference {} private class IntArrayToken2 extends TypeReference {} private class IntListToken1 extends TypeReference> {} private class IntListToken2 extends TypeReference> {} private class IntListArrayToken1 extends TypeReference[]> {} private class IntListArrayToken2 extends TypeReference[]> {} // FIXME: Equality will fail: b/14590652 @SmallTest public void testEquals() { // Not an array. component type should be null. TypeReference intToken = new TypeReference() {{ }}; assertEquals(intToken, intToken); assertEquals(intToken, new TypeReference() {{ }}); assertEquals(intToken, new IntTokenOne()); assertEquals(intToken, new IntTokenTwo()); assertEquals(new IntTokenOne(), new IntTokenTwo()); assertEquals(new IntArrayToken1(), new IntArrayToken2()); assertEquals(new IntListToken1(), new IntListToken2()); assertEquals(new IntListArrayToken1(), new IntListArrayToken2()); } @SmallTest public void testComponentType() { // Not an array. component type should be null. TypeReference intToken = new TypeReference() {{ }}; assertNull(intToken.getComponentType()); TypeReference> listToken = new TypeReference>() {{ }}; assertNull(listToken.getComponentType()); TypeReference>> listListToken = new TypeReference>>() {{ }}; assertNull(listListToken.getComponentType()); // Check arrays. Component types should be what we expect. TypeReference intArrayToken = new TypeReference() {{ }}; assertTypeReferenceEquals(intArrayToken.getComponentType(), int.class); TypeReference integerArrayToken = new TypeReference() {{ }}; assertTypeReferenceEquals(integerArrayToken.getComponentType(), Integer.class); assertEquals(new IntArrayToken1().getComponentType(), new IntArrayToken2().getComponentType()); assertEquals(new IntListArrayToken1().getComponentType(), new IntListArrayToken2().getComponentType()); // FIXME: Equality will fail: b/14590652 TypeReference[]> listArrayToken = new TypeReference[]>() {{ }}; assertEquals(listToken, listArrayToken.getComponentType()); } }