blob: bfa4dbd04952079320fa7810216bfc439c825296 [file] [log] [blame]
/*
* Copyright (C) 2017 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.google.android.exoplayer2.source;
import static com.google.android.exoplayer2.C.INDEX_UNSET;
import static com.google.common.truth.Truth.assertThat;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.source.ShuffleOrder.DefaultShuffleOrder;
import com.google.android.exoplayer2.source.ShuffleOrder.UnshuffledShuffleOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Unit test for {@link ShuffleOrder}. */
@RunWith(AndroidJUnit4.class)
public final class ShuffleOrderTest {
public static final long RANDOM_SEED = 1234567890L;
@Test
public void defaultShuffleOrder() {
assertShuffleOrderCorrectness(new DefaultShuffleOrder(0, RANDOM_SEED), 0);
assertShuffleOrderCorrectness(new DefaultShuffleOrder(1, RANDOM_SEED), 1);
assertShuffleOrderCorrectness(new DefaultShuffleOrder(5, RANDOM_SEED), 5);
for (int initialLength = 0; initialLength < 4; initialLength++) {
for (int insertionPoint = 0; insertionPoint <= initialLength; insertionPoint += 2) {
testCloneAndInsert(new DefaultShuffleOrder(initialLength, RANDOM_SEED), insertionPoint, 0);
testCloneAndInsert(new DefaultShuffleOrder(initialLength, RANDOM_SEED), insertionPoint, 1);
testCloneAndInsert(new DefaultShuffleOrder(initialLength, RANDOM_SEED), insertionPoint, 5);
}
}
testCloneAndRemove(new DefaultShuffleOrder(5, RANDOM_SEED), 0, 1);
testCloneAndRemove(new DefaultShuffleOrder(5, RANDOM_SEED), 2, 3);
testCloneAndRemove(new DefaultShuffleOrder(5, RANDOM_SEED), 4, 5);
testCloneAndRemove(new DefaultShuffleOrder(1, RANDOM_SEED), 0, 1);
testCloneAndRemove(new DefaultShuffleOrder(1000, RANDOM_SEED), 0, 1000);
testCloneAndRemove(new DefaultShuffleOrder(1000, RANDOM_SEED), 0, 999);
testCloneAndRemove(new DefaultShuffleOrder(1000, RANDOM_SEED), 0, 500);
testCloneAndRemove(new DefaultShuffleOrder(1000, RANDOM_SEED), 100, 600);
testCloneAndRemove(new DefaultShuffleOrder(1000, RANDOM_SEED), 500, 1000);
}
@Test
public void defaultShuffleOrderSideloaded() {
int[] shuffledIndices = new int[] {2, 1, 0, 4, 3};
ShuffleOrder shuffleOrder = new DefaultShuffleOrder(shuffledIndices, RANDOM_SEED);
assertThat(shuffleOrder.getFirstIndex()).isEqualTo(2);
assertThat(shuffleOrder.getLastIndex()).isEqualTo(3);
for (int i = 0; i < 4; i++) {
assertThat(shuffleOrder.getNextIndex(shuffledIndices[i])).isEqualTo(shuffledIndices[i + 1]);
}
assertThat(shuffleOrder.getNextIndex(3)).isEqualTo(C.INDEX_UNSET);
for (int i = 4; i > 0; i--) {
assertThat(shuffleOrder.getPreviousIndex(shuffledIndices[i]))
.isEqualTo(shuffledIndices[i - 1]);
}
assertThat(shuffleOrder.getPreviousIndex(2)).isEqualTo(C.INDEX_UNSET);
}
@Test
public void unshuffledShuffleOrder() {
assertShuffleOrderCorrectness(new UnshuffledShuffleOrder(0), 0);
assertShuffleOrderCorrectness(new UnshuffledShuffleOrder(1), 1);
assertShuffleOrderCorrectness(new UnshuffledShuffleOrder(5), 5);
for (int initialLength = 0; initialLength < 4; initialLength++) {
for (int insertionPoint = 0; insertionPoint <= initialLength; insertionPoint += 2) {
testCloneAndInsert(new UnshuffledShuffleOrder(initialLength), insertionPoint, 0);
testCloneAndInsert(new UnshuffledShuffleOrder(initialLength), insertionPoint, 1);
testCloneAndInsert(new UnshuffledShuffleOrder(initialLength), insertionPoint, 5);
}
}
testCloneAndRemove(new UnshuffledShuffleOrder(5), 0, 1);
testCloneAndRemove(new UnshuffledShuffleOrder(5), 2, 3);
testCloneAndRemove(new UnshuffledShuffleOrder(5), 4, 5);
testCloneAndRemove(new UnshuffledShuffleOrder(1), 0, 1);
testCloneAndRemove(new UnshuffledShuffleOrder(1000), 0, 1000);
testCloneAndRemove(new UnshuffledShuffleOrder(1000), 0, 999);
testCloneAndRemove(new UnshuffledShuffleOrder(1000), 0, 500);
testCloneAndRemove(new UnshuffledShuffleOrder(1000), 100, 600);
testCloneAndRemove(new UnshuffledShuffleOrder(1000), 500, 1000);
}
@Test
public void unshuffledShuffleOrderIsUnshuffled() {
ShuffleOrder shuffleOrder = new UnshuffledShuffleOrder(5);
assertThat(shuffleOrder.getFirstIndex()).isEqualTo(0);
assertThat(shuffleOrder.getLastIndex()).isEqualTo(4);
for (int i = 0; i < 4; i++) {
assertThat(shuffleOrder.getNextIndex(i)).isEqualTo(i + 1);
}
}
private static void assertShuffleOrderCorrectness(ShuffleOrder shuffleOrder, int length) {
assertThat(shuffleOrder.getLength()).isEqualTo(length);
if (length == 0) {
assertThat(shuffleOrder.getFirstIndex()).isEqualTo(INDEX_UNSET);
assertThat(shuffleOrder.getLastIndex()).isEqualTo(INDEX_UNSET);
} else {
int[] indices = new int[length];
indices[0] = shuffleOrder.getFirstIndex();
assertThat(shuffleOrder.getPreviousIndex(indices[0])).isEqualTo(INDEX_UNSET);
for (int i = 1; i < length; i++) {
indices[i] = shuffleOrder.getNextIndex(indices[i - 1]);
assertThat(shuffleOrder.getPreviousIndex(indices[i])).isEqualTo(indices[i - 1]);
for (int j = 0; j < i; j++) {
assertThat(indices[i] != indices[j]).isTrue();
}
}
assertThat(shuffleOrder.getLastIndex()).isEqualTo(indices[length - 1]);
assertThat(shuffleOrder.getNextIndex(indices[length - 1])).isEqualTo(INDEX_UNSET);
for (int i = 0; i < length; i++) {
assertThat(indices[i] >= 0).isTrue();
assertThat(indices[i] < length).isTrue();
}
}
}
private static void testCloneAndInsert(ShuffleOrder shuffleOrder, int position, int count) {
ShuffleOrder newOrder = shuffleOrder.cloneAndInsert(position, count);
assertShuffleOrderCorrectness(newOrder, shuffleOrder.getLength() + count);
// Assert all elements still have the relative same order
for (int i = 0; i < shuffleOrder.getLength(); i++) {
int expectedNextIndex = shuffleOrder.getNextIndex(i);
if (expectedNextIndex != C.INDEX_UNSET && expectedNextIndex >= position) {
expectedNextIndex += count;
}
int newNextIndex = newOrder.getNextIndex(i < position ? i : i + count);
while (newNextIndex >= position && newNextIndex < position + count) {
newNextIndex = newOrder.getNextIndex(newNextIndex);
}
assertThat(newNextIndex).isEqualTo(expectedNextIndex);
}
}
private static void testCloneAndRemove(
ShuffleOrder shuffleOrder, int indexFrom, int indexToExclusive) {
int numberOfElementsToRemove = indexToExclusive - indexFrom;
ShuffleOrder newOrder = shuffleOrder.cloneAndRemove(indexFrom, indexToExclusive);
assertShuffleOrderCorrectness(newOrder, shuffleOrder.getLength() - numberOfElementsToRemove);
// Assert all elements still have the relative same order
for (int i = 0; i < shuffleOrder.getLength(); i++) {
if (i >= indexFrom && i < indexToExclusive) {
continue;
}
int expectedNextIndex = shuffleOrder.getNextIndex(i);
while (expectedNextIndex >= indexFrom && expectedNextIndex < indexToExclusive) {
expectedNextIndex = shuffleOrder.getNextIndex(expectedNextIndex);
}
if (expectedNextIndex != C.INDEX_UNSET && expectedNextIndex >= indexFrom) {
expectedNextIndex -= numberOfElementsToRemove;
}
int newNextIndex = newOrder.getNextIndex(i < indexFrom ? i : i - numberOfElementsToRemove);
assertThat(newNextIndex).isEqualTo(expectedNextIndex);
}
}
}