Add ForwardingTimelineTest

PiperOrigin-RevId: 703029260
This commit is contained in:
ibaker 2024-12-05 01:56:06 -08:00 committed by Copybara-Service
parent 5ab9a7856f
commit 92e0b5978f
2 changed files with 83 additions and 17 deletions

View File

@ -0,0 +1,46 @@
/*
* Copyright 2024 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 androidx.media3.exoplayer.source;
import static androidx.media3.test.utils.TestUtil.assertForwardingClassForwardsAllMethodsExcept;
import static androidx.media3.test.utils.TestUtil.assertForwardingClassOverridesAllMethodsExcept;
import androidx.media3.common.Timeline;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.collect.ImmutableSet;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Unit tests for {@link ForwardingTimeline}. */
@RunWith(AndroidJUnit4.class)
public class ForwardingTimelineTest {
@Test
public void overridesAllMethods() throws Exception {
assertForwardingClassOverridesAllMethodsExcept(
Timeline.class,
ForwardingTimeline.class,
ImmutableSet.of("equals", "hashCode", "getPeriodByUid"));
}
@Test
public void forwardsAllMethods() throws Exception {
assertForwardingClassForwardsAllMethodsExcept(
Timeline.class,
delegate -> new ForwardingTimeline(delegate) {},
ImmutableSet.of("equals", "hashCode", "getPeriodByUid"));
}
}

View File

@ -58,6 +58,7 @@ import com.google.common.base.Function;
import com.google.common.collect.BoundType; import com.google.common.collect.BoundType;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Ordering; import com.google.common.collect.Ordering;
import com.google.common.collect.Range; import com.google.common.collect.Range;
import com.google.common.io.ByteStreams; import com.google.common.io.ByteStreams;
@ -599,6 +600,17 @@ public class TestUtil {
return buffer; return buffer;
} }
/**
* Returns all the public overridable methods of a Java class (except those defined by {@link
* Object}).
*/
public static Iterable<Method> getPublicOverridableMethods(Class<?> clazz) {
return Iterables.filter(
getPublicMethods(clazz),
method ->
!Modifier.isFinal(method.getModifiers()) && !Modifier.isStatic(method.getModifiers()));
}
/** Returns all the public methods of a Java class (except those defined by {@link Object}). */ /** Returns all the public methods of a Java class (except those defined by {@link Object}). */
public static List<Method> getPublicMethods(Class<?> clazz) { public static List<Method> getPublicMethods(Class<?> clazz) {
// Run a BFS over all extended types to inspect them all. // Run a BFS over all extended types to inspect them all.
@ -631,12 +643,25 @@ public class TestUtil {
} }
/** /**
* Use reflection to assert that every method declared on {@code superType} is overridden by * Use reflection to assert that every non-final method declared on {@code superType} is
* {@code forwardingType}. * overridden by {@code forwardingType}.
*/ */
public static <T> void assertForwardingClassOverridesAllMethods( public static <T> void assertForwardingClassOverridesAllMethods(
Class<T> superType, Class<? extends T> forwardingType) throws NoSuchMethodException { Class<T> superType, Class<? extends T> forwardingType) throws NoSuchMethodException {
for (Method method : TestUtil.getPublicMethods(superType)) { assertForwardingClassOverridesAllMethodsExcept(superType, forwardingType, ImmutableSet.of());
}
/**
* Use reflection to assert that every non-final, non-excluded method declared on {@code
* superType} is overridden by {@code forwardingType}.
*/
public static <T> void assertForwardingClassOverridesAllMethodsExcept(
Class<T> superType, Class<? extends T> forwardingType, Set<String> excludedMethods)
throws NoSuchMethodException {
for (Method method : TestUtil.getPublicOverridableMethods(superType)) {
if (excludedMethods.contains(method.getName())) {
continue;
}
assertThat( assertThat(
forwardingType forwardingType
.getDeclaredMethod(method.getName(), method.getParameterTypes()) .getDeclaredMethod(method.getName(), method.getParameterTypes())
@ -646,24 +671,22 @@ public class TestUtil {
} }
/** /**
* Use reflection to assert calling every method declared on {@code superType} on an instance of * Use reflection to assert that calling every non-final method declared on {@code superType} on
* {@code forwardingType} results in the call being forwarded to the {@code superType} delegate. * an instance of {@code forwardingType} results in the call being forwarded to the {@code
* superType} delegate.
*/ */
public static <T extends @NonNull Object, F extends T> public static <T extends @NonNull Object, F extends T>
void assertForwardingClassForwardsAllMethods( void assertForwardingClassForwardsAllMethods(
Class<T> superType, Function<T, F> forwardingInstanceFactory) Class<T> superType, Function<T, F> forwardingInstanceFactory)
throws InvocationTargetException, throws InvocationTargetException, IllegalAccessException {
IllegalAccessException,
NoSuchMethodException,
InstantiationException {
assertForwardingClassForwardsAllMethodsExcept( assertForwardingClassForwardsAllMethodsExcept(
superType, forwardingInstanceFactory, /* excludedMethods= */ ImmutableSet.of()); superType, forwardingInstanceFactory, /* excludedMethods= */ ImmutableSet.of());
} }
/** /**
* Use reflection to assert calling every non-excluded method declared on {@code superType} on an * Use reflection to assert that calling every non-final, non-excluded method declared on {@code
* instance of {@code forwardingType} results in the call being forwarded to the {@code superType} * superType} on an instance of {@code forwardingType} results in the call being forwarded to the
* delegate. * {@code superType} delegate.
*/ */
// The nullness checker is deliberately over-conservative and doesn't permit passing a null // The nullness checker is deliberately over-conservative and doesn't permit passing a null
// parameter to method.invoke(), even if the real method does accept null. Regardless, we expect // parameter to method.invoke(), even if the real method does accept null. Regardless, we expect
@ -674,11 +697,8 @@ public class TestUtil {
public static <T extends @NonNull Object, F extends T> public static <T extends @NonNull Object, F extends T>
void assertForwardingClassForwardsAllMethodsExcept( void assertForwardingClassForwardsAllMethodsExcept(
Class<T> superType, Function<T, F> forwardingInstanceFactory, Set<String> excludedMethods) Class<T> superType, Function<T, F> forwardingInstanceFactory, Set<String> excludedMethods)
throws InvocationTargetException, throws InvocationTargetException, IllegalAccessException {
IllegalAccessException, for (Method method : getPublicOverridableMethods(superType)) {
NoSuchMethodException,
InstantiationException {
for (Method method : getPublicMethods(superType)) {
if (excludedMethods.contains(method.getName())) { if (excludedMethods.contains(method.getName())) {
continue; continue;
} }