diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/source/ForwardingTimelineTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/source/ForwardingTimelineTest.java new file mode 100644 index 0000000000..3105d49cf9 --- /dev/null +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/source/ForwardingTimelineTest.java @@ -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")); + } +} diff --git a/libraries/test_utils/src/main/java/androidx/media3/test/utils/TestUtil.java b/libraries/test_utils/src/main/java/androidx/media3/test/utils/TestUtil.java index 90fd63eb54..5a8414f6de 100644 --- a/libraries/test_utils/src/main/java/androidx/media3/test/utils/TestUtil.java +++ b/libraries/test_utils/src/main/java/androidx/media3/test/utils/TestUtil.java @@ -58,6 +58,7 @@ import com.google.common.base.Function; import com.google.common.collect.BoundType; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; import com.google.common.collect.Ordering; import com.google.common.collect.Range; import com.google.common.io.ByteStreams; @@ -599,6 +600,17 @@ public class TestUtil { return buffer; } + /** + * Returns all the public overridable methods of a Java class (except those defined by {@link + * Object}). + */ + public static Iterable 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}). */ public static List getPublicMethods(Class clazz) { // 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 - * {@code forwardingType}. + * Use reflection to assert that every non-final method declared on {@code superType} is + * overridden by {@code forwardingType}. */ public static void assertForwardingClassOverridesAllMethods( Class superType, Class 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 void assertForwardingClassOverridesAllMethodsExcept( + Class superType, Class forwardingType, Set excludedMethods) + throws NoSuchMethodException { + for (Method method : TestUtil.getPublicOverridableMethods(superType)) { + if (excludedMethods.contains(method.getName())) { + continue; + } assertThat( forwardingType .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 - * {@code forwardingType} results in the call being forwarded to the {@code superType} delegate. + * Use reflection to assert that calling every non-final method declared on {@code superType} on + * an instance of {@code forwardingType} results in the call being forwarded to the {@code + * superType} delegate. */ public static void assertForwardingClassForwardsAllMethods( Class superType, Function forwardingInstanceFactory) - throws InvocationTargetException, - IllegalAccessException, - NoSuchMethodException, - InstantiationException { + throws InvocationTargetException, IllegalAccessException { assertForwardingClassForwardsAllMethodsExcept( superType, forwardingInstanceFactory, /* excludedMethods= */ ImmutableSet.of()); } /** - * Use reflection to assert calling every non-excluded method declared on {@code superType} on an - * instance of {@code forwardingType} results in the call being forwarded to the {@code superType} - * delegate. + * Use reflection to assert that calling every non-final, non-excluded method declared on {@code + * superType} on an instance of {@code forwardingType} results in the call being forwarded to the + * {@code superType} delegate. */ // 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 @@ -674,11 +697,8 @@ public class TestUtil { public static void assertForwardingClassForwardsAllMethodsExcept( Class superType, Function forwardingInstanceFactory, Set excludedMethods) - throws InvocationTargetException, - IllegalAccessException, - NoSuchMethodException, - InstantiationException { - for (Method method : getPublicMethods(superType)) { + throws InvocationTargetException, IllegalAccessException { + for (Method method : getPublicOverridableMethods(superType)) { if (excludedMethods.contains(method.getName())) { continue; }