Commit 6c82431e by tonihei Committed by Oliver Woodman

Move (almost all) remaining core library instrumentation tests to Robolectric.

There are 4 tests which can't currently be moved:
 - DownloadManagerTest explicitly uses the main looper which isn't easily
   supported because the test runs on this thread.
 - ContentDataSourceTest uses an AssetFileDescriptor which wraps a
   ParcelFileDescriptor. It seems Robolectric doesn't correctly forward the
   inner wrapped file descriptor leading to NPE.
 - CacheContentIndexTest and SimpleCacheSpanTest both work fine with Gradle
   but fail with seemingly valid test failures on Blaze.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=185366678
parent fbc6ed2e
Showing with 1510 additions and 1075 deletions
......@@ -34,11 +34,14 @@ public class FlacExtractorTest extends InstrumentationTestCase {
}
public void testSample() throws Exception {
ExtractorAsserts.assertBehavior(new ExtractorFactory() {
@Override
public Extractor create() {
return new FlacExtractor();
}
}, "bear.flac", getInstrumentation());
ExtractorAsserts.assertBehavior(
new ExtractorFactory() {
@Override
public Extractor create() {
return new FlacExtractor();
}
},
"bear.flac",
getInstrumentation().getContext());
}
}
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.google.android.exoplayer2.core.test">
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="26"/>
</manifest>
......@@ -9,4 +9,4 @@ Style: Default,Open Sans Semibold,36,&H00FFFFFF,&H000000FF,&H00020713,&H00000000
Format: Layer, Start, End, Style, Name, Text
Dialogue: 0,Invalid,0:00:01.23,Default,Olly,This is the first subtitle{ignored}.
Dialogue: 0,0:00:02.34,Invalid,Default,Olly,This is the second subtitle \nwith a newline \Nand another.
Dialogue: 0,0:00:04:56,0:00:08:90,Default,Olly,This is the third subtitle, with a comma.
\ No newline at end of file
Dialogue: 0,0:00:04:56,0:00:08:90,Default,Olly,This is the third subtitle, with a comma.
......@@ -9,4 +9,4 @@ Style: Default,Open Sans Semibold,36,&H00FFFFFF,&H000000FF,&H00020713,&H00000000
Format: Layer, Start, End, Style, Name, Text
Dialogue: 0,0:00:00.00, ,Default,Olly,This is the first subtitle.
Dialogue: 0,0:00:02.34, ,Default,Olly,This is the second subtitle \nwith a newline \Nand another.
Dialogue: 0,0:00:04.56, ,Default,Olly,This is the third subtitle, with a comma.
\ No newline at end of file
Dialogue: 0,0:00:04.56, ,Default,Olly,This is the third subtitle, with a comma.
......@@ -9,4 +9,4 @@ Style: Default,Open Sans Semibold,36,&H00FFFFFF,&H000000FF,&H00020713,&H00000000
Format: Layer, Start, End, Style, Name, Text
Dialogue: 0,0:00:00.00,0:00:01.23,Default,Olly,This is the first subtitle{ignored}.
Dialogue: 0,0:00:02.34,0:00:03.45,Default,Olly,This is the second subtitle \nwith a newline \Nand another.
Dialogue: 0,0:00:04:56,0:00:08:90,Default,Olly,This is the third subtitle, with a comma.
\ No newline at end of file
Dialogue: 0,0:00:04:56,0:00:08:90,Default,Olly,This is the third subtitle, with a comma.
Dialogue: 0,0:00:00.00,0:00:01.23,Default,Olly,This is the first subtitle{ignored}.
Dialogue: 0,0:00:02.34,0:00:03.45,Default,Olly,This is the second subtitle \nwith a newline \Nand another.
Dialogue: 0,0:00:04:56,0:00:08:90,Default,Olly,This is the third subtitle, with a comma.
\ No newline at end of file
Dialogue: 0,0:00:04:56,0:00:08:90,Default,Olly,This is the third subtitle, with a comma.
Format: Layer, Start, End, Style, Name, Text
\ No newline at end of file
Format: Layer, Start, End, Style, Name, Text
......@@ -3,4 +3,4 @@ Title: SomeTitle
[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default,Open Sans Semibold,36,&H00FFFFFF,&H000000FF,&H00020713,&H00000000,-1,0,0,0,100,100,0,0,1,1.7,0,2,0,0,28,1
\ No newline at end of file
Style: Default,Open Sans Semibold,36,&H00FFFFFF,&H000000FF,&H00020713,&H00000000,-1,0,0,0,100,100,0,0,1,1.7,0,2,0,0,28,1
......@@ -8,4 +8,4 @@ We interpret it to mean that a subtitle extends to the start of the next one.
3
00:00:03,456 -->
Or to the end of the media.
\ No newline at end of file
Or to the end of the media.
......@@ -9,4 +9,4 @@ Second subtitle with second line.
3
00:00:04,567 --> 00:00:08,901
This is the third subtitle.
\ No newline at end of file
This is the third subtitle.
......@@ -10,4 +10,4 @@ Second subtitle with second line.
3
00:00:04,567 --> 00:00:08,901
This is the third subtitle.
\ No newline at end of file
This is the third subtitle.
......@@ -8,4 +8,4 @@ Second subtitle with second line.
3
00:00:04,567 --> 00:00:08,901
This is the third subtitle.
\ No newline at end of file
This is the third subtitle.
......@@ -8,4 +8,4 @@ Second subtitle with second line.
3
00:00:04,567 --> 00:00:08,901
This is the third subtitle.
\ No newline at end of file
This is the third subtitle.
......@@ -7,4 +7,4 @@ This is the first subtitle.
This is the second subtitle.
Second subtitle with second line.
3
\ No newline at end of file
3
......@@ -9,4 +9,4 @@ Second subtitle with second line.
3
00:00:04,567 --> 00:00:08,901
This is the third subtitle.
\ No newline at end of file
This is the third subtitle.
......@@ -22,13 +22,11 @@ import android.media.MediaCodec;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit test for {@link C}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public class CTest {
@SuppressLint("InlinedApi")
......
......@@ -30,13 +30,11 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit test for {@link DefaultMediaClock}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public class DefaultMediaClockTest {
private static final long TEST_POSITION_US = 123456789012345678L;
......@@ -377,6 +375,7 @@ public class DefaultMediaClockTest {
assertThat(mediaClock.syncAndGetPositionUs()).isEqualTo(positionAtStartUs);
}
@SuppressWarnings("HidingField")
private static class MediaClockRenderer extends FakeMediaClockRenderer {
private final boolean playbackParametersAreMutable;
......
......@@ -55,11 +55,7 @@ import org.robolectric.annotation.Config;
/** Unit test for {@link ExoPlayer}. */
@RunWith(RobolectricTestRunner.class)
@Config(
sdk = Config.TARGET_SDK,
manifest = Config.NONE,
shadows = {RobolectricUtil.CustomLooper.class, RobolectricUtil.CustomMessageQueue.class}
)
@Config(shadows = {RobolectricUtil.CustomLooper.class, RobolectricUtil.CustomMessageQueue.class})
public final class ExoPlayerTest {
/**
......
......@@ -39,13 +39,11 @@ import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit test for {@link Format}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class FormatTest {
private static final List<byte[]> INIT_DATA;
......
......@@ -18,23 +18,26 @@ package com.google.android.exoplayer2;
import com.google.android.exoplayer2.testutil.FakeTimeline;
import com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinition;
import com.google.android.exoplayer2.testutil.TimelineAsserts;
import junit.framework.TestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/**
* Unit test for {@link Timeline}.
*/
public class TimelineTest extends TestCase {
/** Unit test for {@link Timeline}. */
@RunWith(RobolectricTestRunner.class)
public class TimelineTest {
@Test
public void testEmptyTimeline() {
TimelineAsserts.assertEmpty(Timeline.EMPTY);
}
@Test
public void testSinglePeriodTimeline() {
Timeline timeline = new FakeTimeline(new TimelineWindowDefinition(1, 111));
TimelineAsserts.assertWindowIds(timeline, 111);
TimelineAsserts.assertPeriodCounts(timeline, 1);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_OFF, false,
C.INDEX_UNSET);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_OFF, false, C.INDEX_UNSET);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ONE, false, 0);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ALL, false, 0);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_OFF, false, C.INDEX_UNSET);
......@@ -42,12 +45,13 @@ public class TimelineTest extends TestCase {
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ALL, false, 0);
}
@Test
public void testMultiPeriodTimeline() {
Timeline timeline = new FakeTimeline(new TimelineWindowDefinition(5, 111));
TimelineAsserts.assertWindowIds(timeline, 111);
TimelineAsserts.assertPeriodCounts(timeline, 5);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_OFF, false,
C.INDEX_UNSET);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_OFF, false, C.INDEX_UNSET);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ONE, false, 0);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ALL, false, 0);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_OFF, false, C.INDEX_UNSET);
......
......@@ -46,7 +46,6 @@ import org.robolectric.annotation.Config;
* Unit test for {@link SimpleDecoderAudioRenderer}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public class SimpleDecoderAudioRendererTest {
private static final Format FORMAT = Format.createSampleFormat(null, MimeTypes.AUDIO_RAW, 0);
......
......@@ -23,13 +23,11 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit test for {@link SonicAudioProcessor}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class SonicAudioProcessorTest {
private SonicAudioProcessor sonicAudioProcessor;
......
......@@ -19,7 +19,6 @@ import static com.google.common.truth.Truth.assertThat;
import com.google.android.exoplayer2.C;
import java.nio.charset.Charset;
import java.util.Arrays;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
......@@ -32,7 +31,7 @@ import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
public final class ClearKeyUtilTest {
@Config(sdk = 26, manifest = Config.NONE)
@Config(sdk = 26)
@Test
public void testAdjustResponseDataV26() {
byte[] data = ("{\"keys\":[{"
......@@ -47,10 +46,10 @@ public final class ClearKeyUtilTest {
+ "\"kid\":\"ab\\/cde+f\"}],"
+ "\"type\":\"abc_def-"
+ "\"}").getBytes(Charset.forName(C.UTF8_NAME));
assertThat(Arrays.equals(expected, ClearKeyUtil.adjustResponseData(data))).isTrue();
assertThat(ClearKeyUtil.adjustResponseData(data)).isEqualTo(expected);
}
@Config(sdk = 26, manifest = Config.NONE)
@Config(sdk = 26)
@Test
public void testAdjustRequestDataV26() {
byte[] data = "{\"kids\":[\"abc+def/\",\"ab+cde/f\"],\"type\":\"abc+def/\"}"
......@@ -58,7 +57,7 @@ public final class ClearKeyUtilTest {
// We expect "+" and "/" to be replaced with "-" and "_" respectively, for "kids".
byte[] expected = "{\"kids\":[\"abc-def_\",\"ab-cde_f\"],\"type\":\"abc+def/\"}"
.getBytes(Charset.forName(C.UTF8_NAME));
assertThat(Arrays.equals(expected, ClearKeyUtil.adjustRequestData(data))).isTrue();
assertThat(ClearKeyUtil.adjustRequestData(data)).isEqualTo(expected);
}
}
......@@ -30,13 +30,11 @@ import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit test for {@link DrmInitData}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public class DrmInitDataTest {
private static final SchemeData DATA_1 = new SchemeData(WIDEVINE_UUID, VIDEO_MP4,
......
......@@ -16,42 +16,48 @@
package com.google.android.exoplayer2.drm;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.when;
import android.test.InstrumentationTestCase;
import android.util.Pair;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.RobolectricUtil;
import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
import com.google.android.exoplayer2.testutil.MockitoUtil;
import java.util.HashMap;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Tests {@link OfflineLicenseHelper}.
*/
public class OfflineLicenseHelperTest extends InstrumentationTestCase {
/** Tests {@link OfflineLicenseHelper}. */
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {RobolectricUtil.CustomLooper.class, RobolectricUtil.CustomMessageQueue.class})
public class OfflineLicenseHelperTest {
private OfflineLicenseHelper<?> offlineLicenseHelper;
@Mock private MediaDrmCallback mediaDrmCallback;
@Mock private ExoMediaDrm<ExoMediaCrypto> mediaDrm;
@Override
protected void setUp() throws Exception {
super.setUp();
MockitoUtil.setUpMockito(this);
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
when(mediaDrm.openSession()).thenReturn(new byte[] {1, 2, 3});
offlineLicenseHelper = new OfflineLicenseHelper<>(C.WIDEVINE_UUID, mediaDrm, mediaDrmCallback,
null);
offlineLicenseHelper =
new OfflineLicenseHelper<>(C.WIDEVINE_UUID, mediaDrm, mediaDrmCallback, null);
}
@Override
protected void tearDown() throws Exception {
@After
public void tearDown() throws Exception {
offlineLicenseHelper.release();
offlineLicenseHelper = null;
super.tearDown();
}
@Test
public void testDownloadRenewReleaseKey() throws Exception {
setStubLicenseAndPlaybackDurationValues(1000, 200);
......@@ -72,6 +78,7 @@ public class OfflineLicenseHelperTest extends InstrumentationTestCase {
offlineLicenseHelper.releaseLicense(offlineLicenseKeySetId2);
}
@Test
public void testDownloadLicenseFailsIfNullInitData() throws Exception {
try {
offlineLicenseHelper.downloadLicense(null);
......@@ -81,6 +88,7 @@ public class OfflineLicenseHelperTest extends InstrumentationTestCase {
}
}
@Test
public void testDownloadLicenseFailsIfNoKeySetIdIsReturned() throws Exception {
setStubLicenseAndPlaybackDurationValues(1000, 200);
......@@ -89,6 +97,7 @@ public class OfflineLicenseHelperTest extends InstrumentationTestCase {
assertThat(offlineLicenseKeySetId).isNull();
}
@Test
public void testDownloadLicenseDoesNotFailIfDurationNotAvailable() throws Exception {
setDefaultStubKeySetId();
......@@ -97,6 +106,7 @@ public class OfflineLicenseHelperTest extends InstrumentationTestCase {
assertThat(offlineLicenseKeySetId).isNotNull();
}
@Test
public void testGetLicenseDurationRemainingSec() throws Exception {
long licenseDuration = 1000;
int playbackDuration = 200;
......@@ -105,13 +115,14 @@ public class OfflineLicenseHelperTest extends InstrumentationTestCase {
byte[] offlineLicenseKeySetId = offlineLicenseHelper.downloadLicense(newDrmInitData());
Pair<Long, Long> licenseDurationRemainingSec = offlineLicenseHelper
.getLicenseDurationRemainingSec(offlineLicenseKeySetId);
Pair<Long, Long> licenseDurationRemainingSec =
offlineLicenseHelper.getLicenseDurationRemainingSec(offlineLicenseKeySetId);
assertThat(licenseDurationRemainingSec.first).isEqualTo(licenseDuration);
assertThat(licenseDurationRemainingSec.second).isEqualTo(playbackDuration);
}
@Test
public void testGetLicenseDurationRemainingSecExpiredLicense() throws Exception {
long licenseDuration = 0;
int playbackDuration = 0;
......@@ -120,8 +131,8 @@ public class OfflineLicenseHelperTest extends InstrumentationTestCase {
byte[] offlineLicenseKeySetId = offlineLicenseHelper.downloadLicense(newDrmInitData());
Pair<Long, Long> licenseDurationRemainingSec = offlineLicenseHelper
.getLicenseDurationRemainingSec(offlineLicenseKeySetId);
Pair<Long, Long> licenseDurationRemainingSec =
offlineLicenseHelper.getLicenseDurationRemainingSec(offlineLicenseKeySetId);
assertThat(licenseDurationRemainingSec.first).isEqualTo(licenseDuration);
assertThat(licenseDurationRemainingSec.second).isEqualTo(playbackDuration);
......@@ -143,19 +154,18 @@ public class OfflineLicenseHelperTest extends InstrumentationTestCase {
assertThat(actualKeySetId).isEqualTo(expectedKeySetId);
}
private void setStubLicenseAndPlaybackDurationValues(long licenseDuration,
long playbackDuration) {
private void setStubLicenseAndPlaybackDurationValues(
long licenseDuration, long playbackDuration) {
HashMap<String, String> keyStatus = new HashMap<>();
keyStatus.put(WidevineUtil.PROPERTY_LICENSE_DURATION_REMAINING,
String.valueOf(licenseDuration));
keyStatus.put(WidevineUtil.PROPERTY_PLAYBACK_DURATION_REMAINING,
String.valueOf(playbackDuration));
keyStatus.put(
WidevineUtil.PROPERTY_LICENSE_DURATION_REMAINING, String.valueOf(licenseDuration));
keyStatus.put(
WidevineUtil.PROPERTY_PLAYBACK_DURATION_REMAINING, String.valueOf(playbackDuration));
when(mediaDrm.queryKeyStatus(any(byte[].class))).thenReturn(keyStatus);
}
private static DrmInitData newDrmInitData() {
return new DrmInitData(new SchemeData(C.WIDEVINE_UUID, "mimeType",
new byte[] {1, 4, 7, 0, 3, 6}));
return new DrmInitData(
new SchemeData(C.WIDEVINE_UUID, "mimeType", new byte[] {1, 4, 7, 0, 3, 6}));
}
}
......@@ -31,13 +31,11 @@ import java.util.Arrays;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Test for {@link DefaultExtractorInput}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public class DefaultExtractorInputTest {
private static final String TEST_URI = "http://www.google.com";
......
......@@ -21,13 +21,11 @@ import com.google.android.exoplayer2.C;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit test for {@link Extractor}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class ExtractorTest {
@Test
......
......@@ -15,23 +15,26 @@
*/
package com.google.android.exoplayer2.extractor.flv;
import android.test.InstrumentationTestCase;
import com.google.android.exoplayer2.extractor.Extractor;
import com.google.android.exoplayer2.testutil.ExtractorAsserts;
import com.google.android.exoplayer2.testutil.ExtractorAsserts.ExtractorFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/**
* Unit test for {@link FlvExtractor}.
*/
public final class FlvExtractorTest extends InstrumentationTestCase {
/** Unit test for {@link FlvExtractor}. */
@RunWith(RobolectricTestRunner.class)
public final class FlvExtractorTest {
@Test
public void testSample() throws Exception {
ExtractorAsserts.assertBehavior(new ExtractorFactory() {
@Override
public Extractor create() {
return new FlvExtractor();
}
}, "flv/sample.flv", getInstrumentation());
ExtractorAsserts.assertBehavior(
new ExtractorFactory() {
@Override
public Extractor create() {
return new FlvExtractor();
}
},
"flv/sample.flv");
}
}
......@@ -27,13 +27,11 @@ import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Tests {@link DefaultEbmlReader}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public class DefaultEbmlReaderTest {
@Test
......
......@@ -15,41 +15,50 @@
*/
package com.google.android.exoplayer2.extractor.mkv;
import android.test.InstrumentationTestCase;
import com.google.android.exoplayer2.extractor.Extractor;
import com.google.android.exoplayer2.testutil.ExtractorAsserts;
import com.google.android.exoplayer2.testutil.ExtractorAsserts.ExtractorFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/**
* Tests for {@link MatroskaExtractor}.
*/
public final class MatroskaExtractorTest extends InstrumentationTestCase {
/** Tests for {@link MatroskaExtractor}. */
@RunWith(RobolectricTestRunner.class)
public final class MatroskaExtractorTest {
@Test
public void testMkvSample() throws Exception {
ExtractorAsserts.assertBehavior(new ExtractorFactory() {
@Override
public Extractor create() {
return new MatroskaExtractor();
}
}, "mkv/sample.mkv", getInstrumentation());
ExtractorAsserts.assertBehavior(
new ExtractorFactory() {
@Override
public Extractor create() {
return new MatroskaExtractor();
}
},
"mkv/sample.mkv");
}
@Test
public void testWebmSubsampleEncryption() throws Exception {
ExtractorAsserts.assertBehavior(new ExtractorFactory() {
@Override
public Extractor create() {
return new MatroskaExtractor();
}
}, "mkv/subsample_encrypted_noaltref.webm", getInstrumentation());
ExtractorAsserts.assertBehavior(
new ExtractorFactory() {
@Override
public Extractor create() {
return new MatroskaExtractor();
}
},
"mkv/subsample_encrypted_noaltref.webm");
}
@Test
public void testWebmSubsampleEncryptionWithAltrefFrames() throws Exception {
ExtractorAsserts.assertBehavior(new ExtractorFactory() {
@Override
public Extractor create() {
return new MatroskaExtractor();
}
}, "mkv/subsample_encrypted_altref.webm", getInstrumentation());
ExtractorAsserts.assertBehavior(
new ExtractorFactory() {
@Override
public Extractor create() {
return new MatroskaExtractor();
}
},
"mkv/subsample_encrypted_altref.webm");
}
}
......@@ -29,13 +29,11 @@ import java.io.IOException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Tests for {@link VarintReader}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class VarintReaderTest {
private static final byte MAX_BYTE = (byte) 0xFF;
......
......@@ -15,32 +15,38 @@
*/
package com.google.android.exoplayer2.extractor.mp3;
import android.test.InstrumentationTestCase;
import com.google.android.exoplayer2.extractor.Extractor;
import com.google.android.exoplayer2.testutil.ExtractorAsserts;
import com.google.android.exoplayer2.testutil.ExtractorAsserts.ExtractorFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/**
* Unit test for {@link Mp3Extractor}.
*/
public final class Mp3ExtractorTest extends InstrumentationTestCase {
/** Unit test for {@link Mp3Extractor}. */
@RunWith(RobolectricTestRunner.class)
public final class Mp3ExtractorTest {
@Test
public void testMp3Sample() throws Exception {
ExtractorAsserts.assertBehavior(new ExtractorFactory() {
@Override
public Extractor create() {
return new Mp3Extractor();
}
}, "mp3/bear.mp3", getInstrumentation());
ExtractorAsserts.assertBehavior(
new ExtractorFactory() {
@Override
public Extractor create() {
return new Mp3Extractor();
}
},
"mp3/bear.mp3");
}
@Test
public void testTrimmedMp3Sample() throws Exception {
ExtractorAsserts.assertBehavior(new ExtractorFactory() {
@Override
public Extractor create() {
return new Mp3Extractor();
}
}, "mp3/play-trimmed.mp3", getInstrumentation());
ExtractorAsserts.assertBehavior(
new ExtractorFactory() {
@Override
public Extractor create() {
return new Mp3Extractor();
}
},
"mp3/play-trimmed.mp3");
}
}
......@@ -27,13 +27,11 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Tests for {@link XingSeeker}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class XingSeekerTest {
// Xing header/payload from http://storage.googleapis.com/exoplayer-test-media-0/play.mp3.
......
......@@ -22,13 +22,11 @@ import com.google.android.exoplayer2.util.Util;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Tests for {@link AtomParsers}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class AtomParsersTest {
private static final String ATOM_HEADER = "000000000000000000000000";
......
......@@ -15,7 +15,6 @@
*/
package com.google.android.exoplayer2.extractor.mp4;
import android.test.InstrumentationTestCase;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.extractor.Extractor;
import com.google.android.exoplayer2.testutil.ExtractorAsserts;
......@@ -23,23 +22,28 @@ import com.google.android.exoplayer2.testutil.ExtractorAsserts.ExtractorFactory;
import com.google.android.exoplayer2.util.MimeTypes;
import java.util.Collections;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/**
* Unit test for {@link FragmentedMp4Extractor}.
*/
public final class FragmentedMp4ExtractorTest extends InstrumentationTestCase {
/** Unit test for {@link FragmentedMp4Extractor}. */
@RunWith(RobolectricTestRunner.class)
public final class FragmentedMp4ExtractorTest {
@Test
public void testSample() throws Exception {
ExtractorAsserts.assertBehavior(getExtractorFactory(Collections.<Format>emptyList()),
"mp4/sample_fragmented.mp4", getInstrumentation());
ExtractorAsserts.assertBehavior(
getExtractorFactory(Collections.<Format>emptyList()), "mp4/sample_fragmented.mp4");
}
@Test
public void testSampleWithSeiPayloadParsing() throws Exception {
// Enabling the CEA-608 track enables SEI payload parsing.
ExtractorFactory extractorFactory = getExtractorFactory(Collections.singletonList(
Format.createTextSampleFormat(null, MimeTypes.APPLICATION_CEA608, 0, null)));
ExtractorAsserts.assertBehavior(extractorFactory, "mp4/sample_fragmented_sei.mp4",
getInstrumentation());
ExtractorFactory extractorFactory =
getExtractorFactory(
Collections.singletonList(
Format.createTextSampleFormat(null, MimeTypes.APPLICATION_CEA608, 0, null)));
ExtractorAsserts.assertBehavior(extractorFactory, "mp4/sample_fragmented_sei.mp4");
}
private static ExtractorFactory getExtractorFactory(final List<Format> closedCaptionFormats) {
......@@ -50,5 +54,4 @@ public final class FragmentedMp4ExtractorTest extends InstrumentationTestCase {
}
};
}
}
......@@ -16,24 +16,27 @@
package com.google.android.exoplayer2.extractor.mp4;
import android.annotation.TargetApi;
import android.test.InstrumentationTestCase;
import com.google.android.exoplayer2.extractor.Extractor;
import com.google.android.exoplayer2.testutil.ExtractorAsserts;
import com.google.android.exoplayer2.testutil.ExtractorAsserts.ExtractorFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/**
* Tests for {@link Mp4Extractor}.
*/
/** Tests for {@link Mp4Extractor}. */
@TargetApi(16)
public final class Mp4ExtractorTest extends InstrumentationTestCase {
@RunWith(RobolectricTestRunner.class)
public final class Mp4ExtractorTest {
@Test
public void testMp4Sample() throws Exception {
ExtractorAsserts.assertBehavior(new ExtractorFactory() {
@Override
public Extractor create() {
return new Mp4Extractor();
}
}, "mp4/sample.mp4", getInstrumentation());
ExtractorAsserts.assertBehavior(
new ExtractorFactory() {
@Override
public Extractor create() {
return new Mp4Extractor();
}
},
"mp4/sample.mp4");
}
}
......@@ -27,13 +27,11 @@ import java.util.UUID;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Tests for {@link PsshAtomUtil}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class PsshAtomUtilTest {
@Test
......
......@@ -17,19 +17,22 @@ package com.google.android.exoplayer2.extractor.ogg;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.fail;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.testutil.FakeExtractorInput;
import com.google.android.exoplayer2.util.ParsableByteArray;
import java.io.IOException;
import java.util.Random;
import junit.framework.TestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/**
* Unit test for {@link DefaultOggSeeker}.
*/
public final class DefaultOggSeekerTest extends TestCase {
/** Unit test for {@link DefaultOggSeeker}. */
@RunWith(RobolectricTestRunner.class)
public final class DefaultOggSeekerTest {
@Test
public void testSetupWithUnsetEndPositionFails() {
try {
new DefaultOggSeeker(0, C.LENGTH_UNSET, new TestStreamReader(), 1, 1);
......@@ -39,6 +42,7 @@ public final class DefaultOggSeekerTest extends TestCase {
}
}
@Test
public void testSeeking() throws IOException, InterruptedException {
Random random = new Random(0);
for (int i = 0; i < 100; i++) {
......@@ -50,8 +54,13 @@ public final class DefaultOggSeekerTest extends TestCase {
OggTestFile testFile = OggTestFile.generate(random, 1000);
FakeExtractorInput input = new FakeExtractorInput.Builder().setData(testFile.data).build();
TestStreamReader streamReader = new TestStreamReader();
DefaultOggSeeker oggSeeker = new DefaultOggSeeker(0, testFile.data.length, streamReader,
testFile.firstPayloadPageSize, testFile.firstPayloadPageGranulePosition);
DefaultOggSeeker oggSeeker =
new DefaultOggSeeker(
0,
testFile.data.length,
streamReader,
testFile.firstPayloadPageSize,
testFile.firstPayloadPageGranulePosition);
OggPageHeader pageHeader = new OggPageHeader();
while (true) {
......@@ -119,14 +128,19 @@ public final class DefaultOggSeekerTest extends TestCase {
long granuleDiff = currentGranule - targetGranule;
if ((granuleDiff > DefaultOggSeeker.MATCH_RANGE || granuleDiff < 0)
&& positionDiff > DefaultOggSeeker.MATCH_BYTE_RANGE) {
fail("granuleDiff (" + granuleDiff + ") or positionDiff (" + positionDiff
+ ") is more than allowed.");
fail(
"granuleDiff ("
+ granuleDiff
+ ") or positionDiff ("
+ positionDiff
+ ") is more than allowed.");
}
}
}
private long seekTo(FakeExtractorInput input, DefaultOggSeeker oggSeeker, long targetGranule,
int initialPosition) throws IOException, InterruptedException {
private long seekTo(
FakeExtractorInput input, DefaultOggSeeker oggSeeker, long targetGranule, int initialPosition)
throws IOException, InterruptedException {
long nextSeekPosition = initialPosition;
int count = 0;
oggSeeker.resetSeeking();
......@@ -150,8 +164,8 @@ public final class DefaultOggSeekerTest extends TestCase {
}
@Override
protected boolean readHeaders(ParsableByteArray packet, long position,
SetupData setupData) throws IOException, InterruptedException {
protected boolean readHeaders(ParsableByteArray packet, long position, SetupData setupData)
throws IOException, InterruptedException {
return false;
}
}
......
......@@ -28,13 +28,11 @@ import java.util.Random;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit test for {@link DefaultOggSeeker} utility methods.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class DefaultOggSeekerUtilMethodsTest {
private final Random random = new Random(0);
......
......@@ -17,7 +17,6 @@ package com.google.android.exoplayer2.extractor.ogg;
import static com.google.common.truth.Truth.assertThat;
import android.test.InstrumentationTestCase;
import com.google.android.exoplayer2.extractor.Extractor;
import com.google.android.exoplayer2.testutil.ExtractorAsserts;
import com.google.android.exoplayer2.testutil.ExtractorAsserts.ExtractorFactory;
......@@ -25,38 +24,43 @@ import com.google.android.exoplayer2.testutil.FakeExtractorInput;
import com.google.android.exoplayer2.testutil.OggTestData;
import com.google.android.exoplayer2.testutil.TestUtil;
import java.io.IOException;
/**
* Unit test for {@link OggExtractor}.
*/
public final class OggExtractorTest extends InstrumentationTestCase {
private static final ExtractorFactory OGG_EXTRACTOR_FACTORY = new ExtractorFactory() {
@Override
public Extractor create() {
return new OggExtractor();
}
};
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/** Unit test for {@link OggExtractor}. */
@RunWith(RobolectricTestRunner.class)
public final class OggExtractorTest {
private static final ExtractorFactory OGG_EXTRACTOR_FACTORY =
new ExtractorFactory() {
@Override
public Extractor create() {
return new OggExtractor();
}
};
@Test
public void testOpus() throws Exception {
ExtractorAsserts.assertBehavior(OGG_EXTRACTOR_FACTORY, "ogg/bear.opus", getInstrumentation());
ExtractorAsserts.assertBehavior(OGG_EXTRACTOR_FACTORY, "ogg/bear.opus");
}
@Test
public void testFlac() throws Exception {
ExtractorAsserts.assertBehavior(OGG_EXTRACTOR_FACTORY, "ogg/bear_flac.ogg",
getInstrumentation());
ExtractorAsserts.assertBehavior(OGG_EXTRACTOR_FACTORY, "ogg/bear_flac.ogg");
}
@Test
public void testFlacNoSeektable() throws Exception {
ExtractorAsserts.assertBehavior(OGG_EXTRACTOR_FACTORY, "ogg/bear_flac_noseektable.ogg",
getInstrumentation());
ExtractorAsserts.assertBehavior(OGG_EXTRACTOR_FACTORY, "ogg/bear_flac_noseektable.ogg");
}
@Test
public void testVorbis() throws Exception {
ExtractorAsserts.assertBehavior(OGG_EXTRACTOR_FACTORY, "ogg/bear_vorbis.ogg",
getInstrumentation());
ExtractorAsserts.assertBehavior(OGG_EXTRACTOR_FACTORY, "ogg/bear_vorbis.ogg");
}
@Test
public void testSniffVorbis() throws Exception {
byte[] data =
TestUtil.joinByteArrays(
......@@ -66,6 +70,7 @@ public final class OggExtractorTest extends InstrumentationTestCase {
assertThat(sniff(data)).isTrue();
}
@Test
public void testSniffFlac() throws Exception {
byte[] data =
TestUtil.joinByteArrays(
......@@ -75,6 +80,7 @@ public final class OggExtractorTest extends InstrumentationTestCase {
assertThat(sniff(data)).isTrue();
}
@Test
public void testSniffFailsOpusFile() throws Exception {
byte[] data =
TestUtil.joinByteArrays(
......@@ -82,11 +88,13 @@ public final class OggExtractorTest extends InstrumentationTestCase {
assertThat(sniff(data)).isFalse();
}
@Test
public void testSniffFailsInvalidOggHeader() throws Exception {
byte[] data = OggTestData.buildOggHeader(0x00, 0, 1000, 0x00);
assertThat(sniff(data)).isFalse();
}
@Test
public void testSniffInvalidHeader() throws Exception {
byte[] data =
TestUtil.joinByteArrays(
......@@ -96,16 +104,20 @@ public final class OggExtractorTest extends InstrumentationTestCase {
assertThat(sniff(data)).isFalse();
}
@Test
public void testSniffFailsEOF() throws Exception {
byte[] data = OggTestData.buildOggHeader(0x02, 0, 1000, 0x00);
assertThat(sniff(data)).isFalse();
}
private boolean sniff(byte[] data) throws InterruptedException, IOException {
FakeExtractorInput input = new FakeExtractorInput.Builder().setData(data)
.setSimulateIOErrors(true).setSimulateUnknownLength(true).setSimulatePartialReads(true)
.build();
FakeExtractorInput input =
new FakeExtractorInput.Builder()
.setData(data)
.setSimulateIOErrors(true)
.setSimulateUnknownLength(true)
.setSimulatePartialReads(true)
.build();
return TestUtil.sniffTestData(OGG_EXTRACTOR_FACTORY.create(), input);
}
}
......@@ -17,7 +17,6 @@ package com.google.android.exoplayer2.extractor.ogg;
import static com.google.common.truth.Truth.assertThat;
import android.test.InstrumentationTestCase;
import com.google.android.exoplayer2.testutil.FakeExtractorInput;
import com.google.android.exoplayer2.testutil.OggTestData;
import com.google.android.exoplayer2.testutil.TestUtil;
......@@ -25,24 +24,28 @@ import com.google.android.exoplayer2.util.ParsableByteArray;
import java.io.IOException;
import java.util.Arrays;
import java.util.Random;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
/**
* Unit test for {@link OggPacket}.
*/
public final class OggPacketTest extends InstrumentationTestCase {
/** Unit test for {@link OggPacket}. */
@RunWith(RobolectricTestRunner.class)
public final class OggPacketTest {
private static final String TEST_FILE = "ogg/bear.opus";
private Random random;
private OggPacket oggPacket;
@Override
@Before
public void setUp() throws Exception {
super.setUp();
random = new Random(0);
oggPacket = new OggPacket();
}
@Test
public void testReadPacketsWithEmptyPage() throws Exception {
byte[] firstPacket = TestUtil.buildTestData(8, random);
byte[] secondPacket = TestUtil.buildTestData(272, random);
......@@ -107,35 +110,41 @@ public final class OggPacketTest extends InstrumentationTestCase {
assertReadEof(input);
}
@Test
public void testReadPacketWithZeroSizeTerminator() throws Exception {
byte[] firstPacket = TestUtil.buildTestData(255, random);
byte[] secondPacket = TestUtil.buildTestData(8, random);
FakeExtractorInput input = OggTestData.createInput(
TestUtil.joinByteArrays(
OggTestData.buildOggHeader(0x06, 0, 1000, 0x04),
TestUtil.createByteArray(0xFF, 0x00, 0x00, 0x08), // Laces.
firstPacket,
secondPacket), true);
FakeExtractorInput input =
OggTestData.createInput(
TestUtil.joinByteArrays(
OggTestData.buildOggHeader(0x06, 0, 1000, 0x04),
TestUtil.createByteArray(0xFF, 0x00, 0x00, 0x08), // Laces.
firstPacket,
secondPacket),
true);
assertReadPacket(input, firstPacket);
assertReadPacket(input, secondPacket);
assertReadEof(input);
}
@Test
public void testReadContinuedPacketOverTwoPages() throws Exception {
byte[] firstPacket = TestUtil.buildTestData(518);
FakeExtractorInput input = OggTestData.createInput(
TestUtil.joinByteArrays(
// First page.
OggTestData.buildOggHeader(0x02, 0, 1000, 0x02),
TestUtil.createByteArray(0xFF, 0xFF), // Laces.
Arrays.copyOf(firstPacket, 510),
// Second page (continued packet).
OggTestData.buildOggHeader(0x05, 10, 1001, 0x01),
TestUtil.createByteArray(0x08), // Laces.
Arrays.copyOfRange(firstPacket, 510, 510 + 8)), true);
FakeExtractorInput input =
OggTestData.createInput(
TestUtil.joinByteArrays(
// First page.
OggTestData.buildOggHeader(0x02, 0, 1000, 0x02),
TestUtil.createByteArray(0xFF, 0xFF), // Laces.
Arrays.copyOf(firstPacket, 510),
// Second page (continued packet).
OggTestData.buildOggHeader(0x05, 10, 1001, 0x01),
TestUtil.createByteArray(0x08), // Laces.
Arrays.copyOfRange(firstPacket, 510, 510 + 8)),
true);
assertReadPacket(input, firstPacket);
assertThat((oggPacket.getPageHeader().type & 0x04) == 0x04).isTrue();
......@@ -145,27 +154,30 @@ public final class OggPacketTest extends InstrumentationTestCase {
assertReadEof(input);
}
@Test
public void testReadContinuedPacketOverFourPages() throws Exception {
byte[] firstPacket = TestUtil.buildTestData(1028);
FakeExtractorInput input = OggTestData.createInput(
TestUtil.joinByteArrays(
// First page.
OggTestData.buildOggHeader(0x02, 0, 1000, 0x02),
TestUtil.createByteArray(0xFF, 0xFF), // Laces.
Arrays.copyOf(firstPacket, 510),
// Second page (continued packet).
OggTestData.buildOggHeader(0x01, 10, 1001, 0x01),
TestUtil.createByteArray(0xFF), // Laces.
Arrays.copyOfRange(firstPacket, 510, 510 + 255),
// Third page (continued packet).
OggTestData.buildOggHeader(0x01, 10, 1002, 0x01),
TestUtil.createByteArray(0xFF), // Laces.
Arrays.copyOfRange(firstPacket, 510 + 255, 510 + 255 + 255),
// Fourth page (continued packet).
OggTestData.buildOggHeader(0x05, 10, 1003, 0x01),
TestUtil.createByteArray(0x08), // Laces.
Arrays.copyOfRange(firstPacket, 510 + 255 + 255, 510 + 255 + 255 + 8)), true);
FakeExtractorInput input =
OggTestData.createInput(
TestUtil.joinByteArrays(
// First page.
OggTestData.buildOggHeader(0x02, 0, 1000, 0x02),
TestUtil.createByteArray(0xFF, 0xFF), // Laces.
Arrays.copyOf(firstPacket, 510),
// Second page (continued packet).
OggTestData.buildOggHeader(0x01, 10, 1001, 0x01),
TestUtil.createByteArray(0xFF), // Laces.
Arrays.copyOfRange(firstPacket, 510, 510 + 255),
// Third page (continued packet).
OggTestData.buildOggHeader(0x01, 10, 1002, 0x01),
TestUtil.createByteArray(0xFF), // Laces.
Arrays.copyOfRange(firstPacket, 510 + 255, 510 + 255 + 255),
// Fourth page (continued packet).
OggTestData.buildOggHeader(0x05, 10, 1003, 0x01),
TestUtil.createByteArray(0x08), // Laces.
Arrays.copyOfRange(firstPacket, 510 + 255 + 255, 510 + 255 + 255 + 8)),
true);
assertReadPacket(input, firstPacket);
assertThat((oggPacket.getPageHeader().type & 0x04) == 0x04).isTrue();
......@@ -175,37 +187,43 @@ public final class OggPacketTest extends InstrumentationTestCase {
assertReadEof(input);
}
@Test
public void testReadDiscardContinuedPacketAtStart() throws Exception {
byte[] pageBody = TestUtil.buildTestData(256 + 8);
FakeExtractorInput input = OggTestData.createInput(
TestUtil.joinByteArrays(
// Page with a continued packet at start.
OggTestData.buildOggHeader(0x01, 10, 1001, 0x03),
TestUtil.createByteArray(255, 1, 8), // Laces.
pageBody), true);
FakeExtractorInput input =
OggTestData.createInput(
TestUtil.joinByteArrays(
// Page with a continued packet at start.
OggTestData.buildOggHeader(0x01, 10, 1001, 0x03),
TestUtil.createByteArray(255, 1, 8), // Laces.
pageBody),
true);
// Expect the first partial packet to be discarded.
assertReadPacket(input, Arrays.copyOfRange(pageBody, 256, 256 + 8));
assertReadEof(input);
}
@Test
public void testReadZeroSizedPacketsAtEndOfStream() throws Exception {
byte[] firstPacket = TestUtil.buildTestData(8, random);
byte[] secondPacket = TestUtil.buildTestData(8, random);
byte[] thirdPacket = TestUtil.buildTestData(8, random);
FakeExtractorInput input = OggTestData.createInput(
TestUtil.joinByteArrays(
OggTestData.buildOggHeader(0x02, 0, 1000, 0x01),
TestUtil.createByteArray(0x08), // Laces.
firstPacket,
OggTestData.buildOggHeader(0x04, 0, 1001, 0x03),
TestUtil.createByteArray(0x08, 0x00, 0x00), // Laces.
secondPacket,
OggTestData.buildOggHeader(0x04, 0, 1002, 0x03),
TestUtil.createByteArray(0x08, 0x00, 0x00), // Laces.
thirdPacket), true);
FakeExtractorInput input =
OggTestData.createInput(
TestUtil.joinByteArrays(
OggTestData.buildOggHeader(0x02, 0, 1000, 0x01),
TestUtil.createByteArray(0x08), // Laces.
firstPacket,
OggTestData.buildOggHeader(0x04, 0, 1001, 0x03),
TestUtil.createByteArray(0x08, 0x00, 0x00), // Laces.
secondPacket,
OggTestData.buildOggHeader(0x04, 0, 1002, 0x03),
TestUtil.createByteArray(0x08, 0x00, 0x00), // Laces.
thirdPacket),
true);
assertReadPacket(input, firstPacket);
assertReadPacket(input, secondPacket);
......@@ -213,9 +231,9 @@ public final class OggPacketTest extends InstrumentationTestCase {
assertReadEof(input);
}
@Test
public void testParseRealFile() throws IOException, InterruptedException {
byte[] data = TestUtil.getByteArray(getInstrumentation(), TEST_FILE);
byte[] data = TestUtil.getByteArray(RuntimeEnvironment.application, TEST_FILE);
FakeExtractorInput input = new FakeExtractorInput.Builder().setData(data).build();
int packetCounter = 0;
while (readPacket(input)) {
......@@ -236,8 +254,7 @@ public final class OggPacketTest extends InstrumentationTestCase {
assertThat(readPacket(extractorInput)).isFalse();
}
private boolean readPacket(FakeExtractorInput input)
throws InterruptedException, IOException {
private boolean readPacket(FakeExtractorInput input) throws InterruptedException, IOException {
while (true) {
try {
return oggPacket.populate(input);
......@@ -246,5 +263,4 @@ public final class OggPacketTest extends InstrumentationTestCase {
}
}
}
}
......@@ -25,13 +25,11 @@ import java.io.IOException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit test for {@link OggPageHeader}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class OggPageHeaderTest {
@Test
......
......@@ -22,9 +22,7 @@ import com.google.android.exoplayer2.testutil.TestUtil;
import java.util.ArrayList;
import java.util.Random;
/**
* Generates test data.
*/
/** Generates test data. */
/* package */ final class OggTestFile {
private static final int MAX_PACKET_LENGTH = 2048;
......@@ -38,8 +36,13 @@ import java.util.Random;
public final int firstPayloadPageSize;
public final long firstPayloadPageGranulePosition;
private OggTestFile(byte[] data, long lastGranule, int packetCount, int pageCount,
int firstPayloadPageSize, long firstPayloadPageGranulePosition) {
private OggTestFile(
byte[] data,
long lastGranule,
int packetCount,
int pageCount,
int firstPayloadPageSize,
long firstPayloadPageGranulePosition) {
this.data = data;
this.lastGranule = lastGranule;
this.packetCount = packetCount;
......@@ -110,7 +113,12 @@ import java.util.Random;
System.arraycopy(data, 0, file, position, data.length);
position += data.length;
}
return new OggTestFile(file, granule, packetCount, pageCount, firstPayloadPageSize,
return new OggTestFile(
file,
granule,
packetCount,
pageCount,
firstPayloadPageSize,
firstPayloadPageGranulePosition);
}
......@@ -123,5 +131,4 @@ import java.util.Random;
fail();
return -1;
}
}
......@@ -21,13 +21,11 @@ import com.google.android.exoplayer2.testutil.TestUtil;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit test for {@link VorbisBitArray}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class VorbisBitArrayTest {
@Test
......
......@@ -29,13 +29,11 @@ import java.io.IOException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit test for {@link VorbisReader}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class VorbisReaderTest {
@Test
......
......@@ -26,13 +26,11 @@ import com.google.android.exoplayer2.util.ParsableByteArray;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit test for {@link VorbisUtil}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class VorbisUtilTest {
@Test
......
......@@ -16,29 +16,38 @@
package com.google.android.exoplayer2.extractor.rawcc;
import android.annotation.TargetApi;
import android.test.InstrumentationTestCase;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.extractor.Extractor;
import com.google.android.exoplayer2.testutil.ExtractorAsserts;
import com.google.android.exoplayer2.testutil.ExtractorAsserts.ExtractorFactory;
import com.google.android.exoplayer2.util.MimeTypes;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/**
* Tests for {@link RawCcExtractor}.
*/
/** Tests for {@link RawCcExtractor}. */
@TargetApi(16)
public final class RawCcExtractorTest extends InstrumentationTestCase {
@RunWith(RobolectricTestRunner.class)
public final class RawCcExtractorTest {
@Test
public void testRawCcSample() throws Exception {
ExtractorAsserts.assertBehavior(
new ExtractorFactory() {
@Override
public Extractor create() {
return new RawCcExtractor(
Format.createTextContainerFormat(null, null, MimeTypes.APPLICATION_CEA608,
"cea608", Format.NO_VALUE, 0, null, 1));
Format.createTextContainerFormat(
null,
null,
MimeTypes.APPLICATION_CEA608,
"cea608",
Format.NO_VALUE,
0,
null,
1));
}
}, "rawcc/sample.rawcc", getInstrumentation());
},
"rawcc/sample.rawcc");
}
}
......@@ -15,23 +15,26 @@
*/
package com.google.android.exoplayer2.extractor.ts;
import android.test.InstrumentationTestCase;
import com.google.android.exoplayer2.extractor.Extractor;
import com.google.android.exoplayer2.testutil.ExtractorAsserts;
import com.google.android.exoplayer2.testutil.ExtractorAsserts.ExtractorFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/**
* Unit test for {@link Ac3Extractor}.
*/
public final class Ac3ExtractorTest extends InstrumentationTestCase {
/** Unit test for {@link Ac3Extractor}. */
@RunWith(RobolectricTestRunner.class)
public final class Ac3ExtractorTest {
@Test
public void testSample() throws Exception {
ExtractorAsserts.assertBehavior(new ExtractorFactory() {
@Override
public Extractor create() {
return new Ac3Extractor();
}
}, "ts/sample.ac3", getInstrumentation());
ExtractorAsserts.assertBehavior(
new ExtractorFactory() {
@Override
public Extractor create() {
return new Ac3Extractor();
}
},
"ts/sample.ac3");
}
}
......@@ -15,23 +15,26 @@
*/
package com.google.android.exoplayer2.extractor.ts;
import android.test.InstrumentationTestCase;
import com.google.android.exoplayer2.extractor.Extractor;
import com.google.android.exoplayer2.testutil.ExtractorAsserts;
import com.google.android.exoplayer2.testutil.ExtractorAsserts.ExtractorFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/**
* Unit test for {@link AdtsExtractor}.
*/
public final class AdtsExtractorTest extends InstrumentationTestCase {
/** Unit test for {@link AdtsExtractor}. */
@RunWith(RobolectricTestRunner.class)
public final class AdtsExtractorTest {
@Test
public void testSample() throws Exception {
ExtractorAsserts.assertBehavior(new ExtractorFactory() {
@Override
public Extractor create() {
return new AdtsExtractor();
}
}, "ts/sample.adts", getInstrumentation());
ExtractorAsserts.assertBehavior(
new ExtractorFactory() {
@Override
public Extractor create() {
return new AdtsExtractor();
}
},
"ts/sample.adts");
}
}
......@@ -23,41 +23,39 @@ import com.google.android.exoplayer2.testutil.FakeTrackOutput;
import com.google.android.exoplayer2.testutil.TestUtil;
import com.google.android.exoplayer2.util.ParsableByteArray;
import java.util.Arrays;
import junit.framework.TestCase;
/**
* Test for {@link AdtsReader}.
*/
public class AdtsReaderTest extends TestCase {
public static final byte[] ID3_DATA_1 = TestUtil.createByteArray(
0x49, 0x44, 0x33, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x54, 0x58,
0x58, 0x58, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x03, 0x00, 0x20, 0x2a,
0x2a, 0x2a, 0x20, 0x54, 0x48, 0x49, 0x53, 0x20, 0x49, 0x53, 0x20, 0x54,
0x69, 0x6d, 0x65, 0x64, 0x20, 0x4d, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74,
0x61, 0x20, 0x40, 0x20, 0x2d, 0x2d, 0x20, 0x30, 0x30, 0x3a, 0x30, 0x30,
0x3a, 0x30, 0x30, 0x2e, 0x30, 0x20, 0x2a, 0x2a, 0x2a, 0x20, 0x00);
public static final byte[] ID3_DATA_2 = TestUtil.createByteArray(
0x49,
0x44, 0x33, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x50, 0x52, 0x49,
0x56, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x63, 0x6f, 0x6d, 0x2e, 0x61,
0x70, 0x70, 0x6c, 0x65, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69,
0x6e, 0x67, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74,
0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
0x61, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0xbb, 0xa0);
public static final byte[] ADTS_HEADER = TestUtil.createByteArray(
0xff, 0xf1, 0x50, 0x80, 0x01, 0xdf, 0xfc);
public static final byte[] ADTS_CONTENT = TestUtil.createByteArray(
0x20, 0x00, 0x20, 0x00, 0x00, 0x80, 0x0e);
private static final byte[] TEST_DATA = TestUtil.joinByteArrays(
ID3_DATA_1,
ID3_DATA_2,
ADTS_HEADER,
ADTS_CONTENT);
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/** Test for {@link AdtsReader}. */
@RunWith(RobolectricTestRunner.class)
public class AdtsReaderTest {
public static final byte[] ID3_DATA_1 =
TestUtil.createByteArray(
0x49, 0x44, 0x33, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x54, 0x58, 0x58, 0x58, 0x00,
0x00, 0x00, 0x33, 0x00, 0x00, 0x03, 0x00, 0x20, 0x2a, 0x2a, 0x2a, 0x20, 0x54, 0x48, 0x49,
0x53, 0x20, 0x49, 0x53, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x64, 0x20, 0x4d, 0x65, 0x74, 0x61,
0x44, 0x61, 0x74, 0x61, 0x20, 0x40, 0x20, 0x2d, 0x2d, 0x20, 0x30, 0x30, 0x3a, 0x30, 0x30,
0x3a, 0x30, 0x30, 0x2e, 0x30, 0x20, 0x2a, 0x2a, 0x2a, 0x20, 0x00);
public static final byte[] ID3_DATA_2 =
TestUtil.createByteArray(
0x49, 0x44, 0x33, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x50, 0x52, 0x49, 0x56, 0x00,
0x00, 0x00, 0x35, 0x00, 0x00, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e,
0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73,
0x70, 0x6f, 0x72, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x54, 0x69, 0x6d, 0x65, 0x73,
0x74, 0x61, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0xbb, 0xa0);
public static final byte[] ADTS_HEADER =
TestUtil.createByteArray(0xff, 0xf1, 0x50, 0x80, 0x01, 0xdf, 0xfc);
public static final byte[] ADTS_CONTENT =
TestUtil.createByteArray(0x20, 0x00, 0x20, 0x00, 0x00, 0x80, 0x0e);
private static final byte[] TEST_DATA =
TestUtil.joinByteArrays(ID3_DATA_1, ID3_DATA_2, ADTS_HEADER, ADTS_CONTENT);
private static final long ADTS_SAMPLE_DURATION = 23219L;
......@@ -67,9 +65,8 @@ public class AdtsReaderTest extends TestCase {
private ParsableByteArray data;
private boolean firstFeed;
@Override
protected void setUp() throws Exception {
super.setUp();
@Before
public void setUp() throws Exception {
FakeExtractorOutput fakeExtractorOutput = new FakeExtractorOutput();
adtsOutput = fakeExtractorOutput.track(0, C.TRACK_TYPE_AUDIO);
id3Output = fakeExtractorOutput.track(1, C.TRACK_TYPE_METADATA);
......@@ -80,6 +77,7 @@ public class AdtsReaderTest extends TestCase {
firstFeed = true;
}
@Test
public void testSkipToNextSample() throws Exception {
for (int i = 1; i <= ID3_DATA_1.length + ID3_DATA_2.length; i++) {
data.setPosition(i);
......@@ -90,50 +88,60 @@ public class AdtsReaderTest extends TestCase {
}
}
@Test
public void testSkipToNextSampleResetsState() throws Exception {
data = new ParsableByteArray(TestUtil.joinByteArrays(
ADTS_HEADER,
ADTS_CONTENT,
// Adts sample missing the first sync byte
Arrays.copyOfRange(ADTS_HEADER, 1, ADTS_HEADER.length),
ADTS_CONTENT));
data =
new ParsableByteArray(
TestUtil.joinByteArrays(
ADTS_HEADER,
ADTS_CONTENT,
// Adts sample missing the first sync byte
Arrays.copyOfRange(ADTS_HEADER, 1, ADTS_HEADER.length),
ADTS_CONTENT));
feed();
assertSampleCounts(0, 1);
adtsOutput.assertSample(0, ADTS_CONTENT, 0, C.BUFFER_FLAG_KEY_FRAME, null);
}
@Test
public void testNoData() throws Exception {
feedLimited(0);
assertSampleCounts(0, 0);
}
@Test
public void testNotEnoughDataForIdentifier() throws Exception {
feedLimited(3 - 1);
assertSampleCounts(0, 0);
}
@Test
public void testNotEnoughDataForHeader() throws Exception {
feedLimited(10 - 1);
assertSampleCounts(0, 0);
}
@Test
public void testNotEnoughDataForWholeId3Packet() throws Exception {
feedLimited(ID3_DATA_1.length - 1);
assertSampleCounts(0, 0);
}
@Test
public void testConsumeWholeId3Packet() throws Exception {
feedLimited(ID3_DATA_1.length);
assertSampleCounts(1, 0);
id3Output.assertSample(0, ID3_DATA_1, 0, C.BUFFER_FLAG_KEY_FRAME, null);
}
@Test
public void testMultiId3Packet() throws Exception {
feedLimited(ID3_DATA_1.length + ID3_DATA_2.length - 1);
assertSampleCounts(1, 0);
id3Output.assertSample(0, ID3_DATA_1, 0, C.BUFFER_FLAG_KEY_FRAME, null);
}
@Test
public void testMultiId3PacketConsumed() throws Exception {
feedLimited(ID3_DATA_1.length + ID3_DATA_2.length);
assertSampleCounts(2, 0);
......@@ -141,6 +149,7 @@ public class AdtsReaderTest extends TestCase {
id3Output.assertSample(1, ID3_DATA_2, 0, C.BUFFER_FLAG_KEY_FRAME, null);
}
@Test
public void testMultiPacketConsumed() throws Exception {
for (int i = 0; i < 10; i++) {
data.setPosition(0);
......@@ -156,6 +165,7 @@ public class AdtsReaderTest extends TestCase {
}
}
@Test
public void testAdtsDataOnly() throws ParserException {
data.setPosition(ID3_DATA_1.length + ID3_DATA_2.length);
feed();
......@@ -185,6 +195,4 @@ public class AdtsReaderTest extends TestCase {
id3Output.assertSampleCount(id3SampleCount);
adtsOutput.assertSampleCount(adtsSampleCount);
}
}
......@@ -15,23 +15,26 @@
*/
package com.google.android.exoplayer2.extractor.ts;
import android.test.InstrumentationTestCase;
import com.google.android.exoplayer2.extractor.Extractor;
import com.google.android.exoplayer2.testutil.ExtractorAsserts;
import com.google.android.exoplayer2.testutil.ExtractorAsserts.ExtractorFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/**
* Unit test for {@link PsExtractor}.
*/
public final class PsExtractorTest extends InstrumentationTestCase {
/** Unit test for {@link PsExtractor}. */
@RunWith(RobolectricTestRunner.class)
public final class PsExtractorTest {
@Test
public void testSample() throws Exception {
ExtractorAsserts.assertBehavior(new ExtractorFactory() {
@Override
public Extractor create() {
return new PsExtractor();
}
}, "ts/sample.ps", getInstrumentation());
ExtractorAsserts.assertBehavior(
new ExtractorFactory() {
@Override
public Extractor create() {
return new PsExtractor();
}
},
"ts/sample.ps");
}
}
......@@ -30,13 +30,11 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Test for {@link SectionReader}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class SectionReaderTest {
private byte[] packetPayload;
......
......@@ -17,7 +17,6 @@ package com.google.android.exoplayer2.extractor.ts;
import static com.google.common.truth.Truth.assertThat;
import android.test.InstrumentationTestCase;
import android.util.SparseArray;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
......@@ -37,27 +36,34 @@ import com.google.android.exoplayer2.util.ParsableByteArray;
import com.google.android.exoplayer2.util.TimestampAdjuster;
import java.io.ByteArrayOutputStream;
import java.util.Random;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
/**
* Unit test for {@link TsExtractor}.
*/
public final class TsExtractorTest extends InstrumentationTestCase {
/** Unit test for {@link TsExtractor}. */
@RunWith(RobolectricTestRunner.class)
public final class TsExtractorTest {
private static final int TS_PACKET_SIZE = 188;
private static final int TS_SYNC_BYTE = 0x47; // First byte of each TS packet.
@Test
public void testSample() throws Exception {
ExtractorAsserts.assertBehavior(new ExtractorFactory() {
@Override
public Extractor create() {
return new TsExtractor();
}
}, "ts/sample.ts", getInstrumentation());
ExtractorAsserts.assertBehavior(
new ExtractorFactory() {
@Override
public Extractor create() {
return new TsExtractor();
}
},
"ts/sample.ts");
}
@Test
public void testIncompleteSample() throws Exception {
Random random = new Random(0);
byte[] fileData = TestUtil.getByteArray(getInstrumentation(), "ts/sample.ts");
byte[] fileData = TestUtil.getByteArray(RuntimeEnvironment.application, "ts/sample.ts");
ByteArrayOutputStream out = new ByteArrayOutputStream(fileData.length * 2);
writeJunkData(out, random.nextInt(TS_PACKET_SIZE - 1) + 1);
out.write(fileData, 0, TS_PACKET_SIZE * 5);
......@@ -69,23 +75,30 @@ public final class TsExtractorTest extends InstrumentationTestCase {
writeJunkData(out, random.nextInt(TS_PACKET_SIZE - 1) + 1);
fileData = out.toByteArray();
ExtractorAsserts.assertOutput(new ExtractorFactory() {
@Override
public Extractor create() {
return new TsExtractor();
}
}, "ts/sample.ts", fileData, getInstrumentation());
ExtractorAsserts.assertOutput(
new ExtractorFactory() {
@Override
public Extractor create() {
return new TsExtractor();
}
},
"ts/sample.ts",
fileData,
RuntimeEnvironment.application);
}
@Test
public void testCustomPesReader() throws Exception {
CustomTsPayloadReaderFactory factory = new CustomTsPayloadReaderFactory(true, false);
TsExtractor tsExtractor = new TsExtractor(TsExtractor.MODE_MULTI_PMT, new TimestampAdjuster(0),
factory);
FakeExtractorInput input = new FakeExtractorInput.Builder()
.setData(TestUtil.getByteArray(getInstrumentation(), "ts/sample.ts"))
.setSimulateIOErrors(false)
.setSimulateUnknownLength(false)
.setSimulatePartialReads(false).build();
TsExtractor tsExtractor =
new TsExtractor(TsExtractor.MODE_MULTI_PMT, new TimestampAdjuster(0), factory);
FakeExtractorInput input =
new FakeExtractorInput.Builder()
.setData(TestUtil.getByteArray(RuntimeEnvironment.application, "ts/sample.ts"))
.setSimulateIOErrors(false)
.setSimulateUnknownLength(false)
.setSimulatePartialReads(false)
.build();
FakeExtractorOutput output = new FakeExtractorOutput();
tsExtractor.init(output);
PositionHolder seekPositionHolder = new PositionHolder();
......@@ -101,15 +114,18 @@ public final class TsExtractorTest extends InstrumentationTestCase {
.isEqualTo(Format.createTextSampleFormat("1/257", "mime", null, 0, 0, "und", null, 0));
}
@Test
public void testCustomInitialSectionReader() throws Exception {
CustomTsPayloadReaderFactory factory = new CustomTsPayloadReaderFactory(false, true);
TsExtractor tsExtractor = new TsExtractor(TsExtractor.MODE_MULTI_PMT, new TimestampAdjuster(0),
factory);
FakeExtractorInput input = new FakeExtractorInput.Builder()
.setData(TestUtil.getByteArray(getInstrumentation(), "ts/sample_with_sdt.ts"))
.setSimulateIOErrors(false)
.setSimulateUnknownLength(false)
.setSimulatePartialReads(false).build();
TsExtractor tsExtractor =
new TsExtractor(TsExtractor.MODE_MULTI_PMT, new TimestampAdjuster(0), factory);
FakeExtractorInput input =
new FakeExtractorInput.Builder()
.setData(TestUtil.getByteArray(RuntimeEnvironment.application, "ts/sample_with_sdt.ts"))
.setSimulateIOErrors(false)
.setSimulateUnknownLength(false)
.setSimulatePartialReads(false)
.build();
tsExtractor.init(new FakeExtractorOutput());
PositionHolder seekPositionHolder = new PositionHolder();
int readResult = Extractor.RESULT_CONTINUE;
......@@ -165,7 +181,6 @@ public final class TsExtractorTest extends InstrumentationTestCase {
return defaultFactory.createPayloadReader(streamType, esInfo);
}
}
}
private static final class CustomEsReader implements ElementaryStreamReader {
......@@ -179,24 +194,22 @@ public final class TsExtractorTest extends InstrumentationTestCase {
}
@Override
public void seek() {
}
public void seek() {}
@Override
public void createTracks(ExtractorOutput extractorOutput, TrackIdGenerator idGenerator) {
idGenerator.generateNewId();
output = extractorOutput.track(idGenerator.getTrackId(), C.TRACK_TYPE_UNKNOWN);
output.format(Format.createTextSampleFormat(idGenerator.getFormatId(), "mime", null, 0, 0,
language, null, 0));
output.format(
Format.createTextSampleFormat(
idGenerator.getFormatId(), "mime", null, 0, 0, language, null, 0));
}
@Override
public void packetStarted(long pesTimeUs, boolean dataAlignmentIndicator) {
}
public void packetStarted(long pesTimeUs, boolean dataAlignmentIndicator) {}
@Override
public void consume(ParsableByteArray data) {
}
public void consume(ParsableByteArray data) {}
@Override
public void packetFinished() {
......@@ -206,7 +219,6 @@ public final class TsExtractorTest extends InstrumentationTestCase {
public TrackOutput getTrackOutput() {
return output;
}
}
private static final class SdtSectionReader implements SectionPayloadReader {
......@@ -214,7 +226,9 @@ public final class TsExtractorTest extends InstrumentationTestCase {
private int consumedSdts;
@Override
public void init(TimestampAdjuster timestampAdjuster, ExtractorOutput extractorOutput,
public void init(
TimestampAdjuster timestampAdjuster,
ExtractorOutput extractorOutput,
TrackIdGenerator idGenerator) {
// Do nothing.
}
......@@ -248,7 +262,5 @@ public final class TsExtractorTest extends InstrumentationTestCase {
}
consumedSdts++;
}
}
}
......@@ -15,23 +15,26 @@
*/
package com.google.android.exoplayer2.extractor.wav;
import android.test.InstrumentationTestCase;
import com.google.android.exoplayer2.extractor.Extractor;
import com.google.android.exoplayer2.testutil.ExtractorAsserts;
import com.google.android.exoplayer2.testutil.ExtractorAsserts.ExtractorFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/**
* Unit test for {@link WavExtractor}.
*/
public final class WavExtractorTest extends InstrumentationTestCase {
/** Unit test for {@link WavExtractor}. */
@RunWith(RobolectricTestRunner.class)
public final class WavExtractorTest {
@Test
public void testSample() throws Exception {
ExtractorAsserts.assertBehavior(new ExtractorFactory() {
@Override
public Extractor create() {
return new WavExtractor();
}
}, "wav/sample.wav", getInstrumentation());
ExtractorAsserts.assertBehavior(
new ExtractorFactory() {
@Override
public Extractor create() {
return new WavExtractor();
}
},
"wav/sample.wav");
}
}
......@@ -23,13 +23,11 @@ import java.nio.ByteBuffer;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Test for {@link EventMessageDecoder}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class EventMessageDecoderTest {
@Test
......
......@@ -24,13 +24,11 @@ import java.nio.ByteBuffer;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit test for {@link EventMessageEncoder}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class EventMessageEncoderTest {
@Test
......
......@@ -21,13 +21,11 @@ import android.os.Parcel;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Test for {@link EventMessage}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class EventMessageTest {
@Test
......
......@@ -21,13 +21,11 @@ import android.os.Parcel;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Test for {@link ChapterFrame}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class ChapterFrameTest {
@Test
......
......@@ -21,13 +21,11 @@ import android.os.Parcel;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Test for {@link ChapterTocFrame}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class ChapterTocFrameTest {
@Test
......
......@@ -25,13 +25,11 @@ import java.nio.charset.Charset;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Test for {@link Id3Decoder}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class Id3DecoderTest {
private static final byte[] TAG_HEADER = new byte[] {73, 68, 51, 4, 0, 0, 0, 0, 0, 0};
......
......@@ -28,13 +28,11 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Test for {@link SpliceInfoDecoder}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class SpliceInfoDecoderTest {
private SpliceInfoDecoder decoder;
......
......@@ -16,10 +16,11 @@
package com.google.android.exoplayer2.source;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import android.test.InstrumentationTestCase;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.RobolectricUtil;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.Timeline.Period;
import com.google.android.exoplayer2.Timeline.Window;
......@@ -30,11 +31,16 @@ import com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinit
import com.google.android.exoplayer2.testutil.MediaSourceTestRunner;
import com.google.android.exoplayer2.testutil.TimelineAsserts;
import java.io.IOException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit tests for {@link ClippingMediaSource}.
*/
public final class ClippingMediaSourceTest extends InstrumentationTestCase {
/** Unit tests for {@link ClippingMediaSource}. */
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {RobolectricUtil.CustomLooper.class, RobolectricUtil.CustomMessageQueue.class})
public final class ClippingMediaSourceTest {
private static final long TEST_PERIOD_DURATION_US = 1000000;
private static final long TEST_CLIP_AMOUNT_US = 300000;
......@@ -42,13 +48,13 @@ public final class ClippingMediaSourceTest extends InstrumentationTestCase {
private Window window;
private Period period;
@Override
protected void setUp() throws Exception {
super.setUp();
@Before
public void setUp() throws Exception {
window = new Timeline.Window();
period = new Timeline.Period();
}
@Test
public void testNoClipping() throws IOException {
Timeline timeline = new SinglePeriodTimeline(C.msToUs(TEST_PERIOD_DURATION_US), true, false);
......@@ -62,6 +68,7 @@ public final class ClippingMediaSourceTest extends InstrumentationTestCase {
.isEqualTo(TEST_PERIOD_DURATION_US);
}
@Test
public void testClippingUnseekableWindowThrows() throws IOException {
Timeline timeline = new SinglePeriodTimeline(C.msToUs(TEST_PERIOD_DURATION_US), false, false);
......@@ -76,67 +83,76 @@ public final class ClippingMediaSourceTest extends InstrumentationTestCase {
}
}
@Test
public void testClippingStart() throws IOException {
Timeline timeline = new SinglePeriodTimeline(C.msToUs(TEST_PERIOD_DURATION_US), true, false);
Timeline clippedTimeline = getClippedTimeline(timeline, TEST_CLIP_AMOUNT_US,
TEST_PERIOD_DURATION_US);
Timeline clippedTimeline =
getClippedTimeline(timeline, TEST_CLIP_AMOUNT_US, TEST_PERIOD_DURATION_US);
assertThat(clippedTimeline.getWindow(0, window).getDurationUs())
.isEqualTo(TEST_PERIOD_DURATION_US - TEST_CLIP_AMOUNT_US);
assertThat(clippedTimeline.getPeriod(0, period).getDurationUs())
.isEqualTo(TEST_PERIOD_DURATION_US - TEST_CLIP_AMOUNT_US);
}
@Test
public void testClippingEnd() throws IOException {
Timeline timeline = new SinglePeriodTimeline(C.msToUs(TEST_PERIOD_DURATION_US), true, false);
Timeline clippedTimeline = getClippedTimeline(timeline, 0,
TEST_PERIOD_DURATION_US - TEST_CLIP_AMOUNT_US);
Timeline clippedTimeline =
getClippedTimeline(timeline, 0, TEST_PERIOD_DURATION_US - TEST_CLIP_AMOUNT_US);
assertThat(clippedTimeline.getWindow(0, window).getDurationUs())
.isEqualTo(TEST_PERIOD_DURATION_US - TEST_CLIP_AMOUNT_US);
assertThat(clippedTimeline.getPeriod(0, period).getDurationUs())
.isEqualTo(TEST_PERIOD_DURATION_US - TEST_CLIP_AMOUNT_US);
}
@Test
public void testClippingStartAndEndInitial() throws IOException {
// Timeline that's dynamic and not seekable. A child source might report such a timeline prior
// to it having loaded sufficient data to establish its duration and seekability. Such timelines
// should not result in clipping failure.
Timeline timeline = new SinglePeriodTimeline(C.TIME_UNSET, /* isSeekable= */ false,
/* isDynamic= */true);
Timeline timeline =
new SinglePeriodTimeline(C.TIME_UNSET, /* isSeekable= */ false, /* isDynamic= */ true);
Timeline clippedTimeline = getClippedTimeline(timeline, TEST_CLIP_AMOUNT_US,
TEST_PERIOD_DURATION_US - TEST_CLIP_AMOUNT_US * 2);
Timeline clippedTimeline =
getClippedTimeline(
timeline, TEST_CLIP_AMOUNT_US, TEST_PERIOD_DURATION_US - TEST_CLIP_AMOUNT_US * 2);
assertThat(clippedTimeline.getWindow(0, window).getDurationUs())
.isEqualTo(TEST_PERIOD_DURATION_US - TEST_CLIP_AMOUNT_US * 3);
assertThat(clippedTimeline.getPeriod(0, period).getDurationUs())
.isEqualTo(TEST_PERIOD_DURATION_US - TEST_CLIP_AMOUNT_US * 3);
}
@Test
public void testClippingStartAndEnd() throws IOException {
Timeline timeline = new SinglePeriodTimeline(C.msToUs(TEST_PERIOD_DURATION_US), true, false);
Timeline clippedTimeline = getClippedTimeline(timeline, TEST_CLIP_AMOUNT_US,
TEST_PERIOD_DURATION_US - TEST_CLIP_AMOUNT_US * 2);
Timeline clippedTimeline =
getClippedTimeline(
timeline, TEST_CLIP_AMOUNT_US, TEST_PERIOD_DURATION_US - TEST_CLIP_AMOUNT_US * 2);
assertThat(clippedTimeline.getWindow(0, window).getDurationUs())
.isEqualTo(TEST_PERIOD_DURATION_US - TEST_CLIP_AMOUNT_US * 3);
assertThat(clippedTimeline.getPeriod(0, period).getDurationUs())
.isEqualTo(TEST_PERIOD_DURATION_US - TEST_CLIP_AMOUNT_US * 3);
}
@Test
public void testWindowAndPeriodIndices() throws IOException {
Timeline timeline = new FakeTimeline(
new TimelineWindowDefinition(1, 111, true, false, TEST_PERIOD_DURATION_US));
Timeline clippedTimeline = getClippedTimeline(timeline, TEST_CLIP_AMOUNT_US,
TEST_PERIOD_DURATION_US - TEST_CLIP_AMOUNT_US);
Timeline timeline =
new FakeTimeline(
new TimelineWindowDefinition(1, 111, true, false, TEST_PERIOD_DURATION_US));
Timeline clippedTimeline =
getClippedTimeline(
timeline, TEST_CLIP_AMOUNT_US, TEST_PERIOD_DURATION_US - TEST_CLIP_AMOUNT_US);
TimelineAsserts.assertWindowIds(clippedTimeline, 111);
TimelineAsserts.assertPeriodCounts(clippedTimeline, 1);
TimelineAsserts.assertPreviousWindowIndices(clippedTimeline, Player.REPEAT_MODE_OFF, false,
C.INDEX_UNSET);
TimelineAsserts.assertPreviousWindowIndices(
clippedTimeline, Player.REPEAT_MODE_OFF, false, C.INDEX_UNSET);
TimelineAsserts.assertPreviousWindowIndices(clippedTimeline, Player.REPEAT_MODE_ONE, false, 0);
TimelineAsserts.assertPreviousWindowIndices(clippedTimeline, Player.REPEAT_MODE_ALL, false, 0);
TimelineAsserts.assertNextWindowIndices(clippedTimeline, Player.REPEAT_MODE_OFF, false,
C.INDEX_UNSET);
TimelineAsserts.assertNextWindowIndices(
clippedTimeline, Player.REPEAT_MODE_OFF, false, C.INDEX_UNSET);
TimelineAsserts.assertNextWindowIndices(clippedTimeline, Player.REPEAT_MODE_ONE, false, 0);
TimelineAsserts.assertNextWindowIndices(clippedTimeline, Player.REPEAT_MODE_ALL, false, 0);
}
......@@ -158,5 +174,4 @@ public final class ClippingMediaSourceTest extends InstrumentationTestCase {
testRunner.release();
}
}
}
......@@ -21,13 +21,11 @@ import com.google.android.exoplayer2.C;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit test for {@link CompositeSequenceableLoader}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class CompositeSequenceableLoaderTest {
/**
......
......@@ -19,6 +19,7 @@ import static com.google.common.truth.Truth.assertThat;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.RobolectricUtil;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
import com.google.android.exoplayer2.testutil.FakeMediaSource;
......@@ -28,13 +29,17 @@ import com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinit
import com.google.android.exoplayer2.testutil.MediaSourceTestRunner;
import com.google.android.exoplayer2.testutil.TimelineAsserts;
import java.io.IOException;
import junit.framework.TestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit tests for {@link ConcatenatingMediaSource}.
*/
public final class ConcatenatingMediaSourceTest extends TestCase {
/** Unit tests for {@link ConcatenatingMediaSource}. */
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {RobolectricUtil.CustomLooper.class, RobolectricUtil.CustomMessageQueue.class})
public final class ConcatenatingMediaSourceTest {
@Test
public void testEmptyConcatenation() throws IOException {
for (boolean atomic : new boolean[] {false, true}) {
Timeline timeline = getConcatenatedTimeline(atomic);
......@@ -48,17 +53,18 @@ public final class ConcatenatingMediaSourceTest extends TestCase {
}
}
@Test
public void testSingleMediaSource() throws IOException {
Timeline timeline = getConcatenatedTimeline(false, createFakeTimeline(3, 111));
TimelineAsserts.assertWindowIds(timeline, 111);
TimelineAsserts.assertPeriodCounts(timeline, 3);
for (boolean shuffled : new boolean[] {false, true}) {
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_OFF, shuffled,
C.INDEX_UNSET);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_OFF, shuffled, C.INDEX_UNSET);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ONE, shuffled, 0);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ALL, shuffled, 0);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_OFF, shuffled,
C.INDEX_UNSET);
TimelineAsserts.assertNextWindowIndices(
timeline, Player.REPEAT_MODE_OFF, shuffled, C.INDEX_UNSET);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ONE, shuffled, 0);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ALL, shuffled, 0);
}
......@@ -67,17 +73,18 @@ public final class ConcatenatingMediaSourceTest extends TestCase {
TimelineAsserts.assertWindowIds(timeline, 111);
TimelineAsserts.assertPeriodCounts(timeline, 3);
for (boolean shuffled : new boolean[] {false, true}) {
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_OFF, shuffled,
C.INDEX_UNSET);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_OFF, shuffled, C.INDEX_UNSET);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ONE, shuffled, 0);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ALL, shuffled, 0);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_OFF, shuffled,
C.INDEX_UNSET);
TimelineAsserts.assertNextWindowIndices(
timeline, Player.REPEAT_MODE_OFF, shuffled, C.INDEX_UNSET);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ONE, shuffled, 0);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ALL, shuffled, 0);
}
}
@Test
public void testMultipleMediaSources() throws IOException {
Timeline[] timelines = {
createFakeTimeline(3, 111), createFakeTimeline(1, 222), createFakeTimeline(3, 333)
......@@ -85,20 +92,20 @@ public final class ConcatenatingMediaSourceTest extends TestCase {
Timeline timeline = getConcatenatedTimeline(false, timelines);
TimelineAsserts.assertWindowIds(timeline, 111, 222, 333);
TimelineAsserts.assertPeriodCounts(timeline, 3, 1, 3);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_OFF, false,
C.INDEX_UNSET, 0, 1);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_OFF, false, C.INDEX_UNSET, 0, 1);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ONE, false, 0, 1, 2);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ALL, false, 2, 0, 1);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_OFF, false,
1, 2, C.INDEX_UNSET);
TimelineAsserts.assertNextWindowIndices(
timeline, Player.REPEAT_MODE_OFF, false, 1, 2, C.INDEX_UNSET);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ONE, false, 0, 1, 2);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ALL, false, 1, 2, 0);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_OFF, true,
1, 2, C.INDEX_UNSET);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_OFF, true, 1, 2, C.INDEX_UNSET);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ONE, true, 0, 1, 2);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ALL, true, 1, 2, 0);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_OFF, true,
C.INDEX_UNSET, 0, 1);
TimelineAsserts.assertNextWindowIndices(
timeline, Player.REPEAT_MODE_OFF, true, C.INDEX_UNSET, 0, 1);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ONE, true, 0, 1, 2);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ALL, true, 2, 0, 1);
assertThat(timeline.getFirstWindowIndex(false)).isEqualTo(0);
......@@ -110,14 +117,14 @@ public final class ConcatenatingMediaSourceTest extends TestCase {
TimelineAsserts.assertWindowIds(timeline, 111, 222, 333);
TimelineAsserts.assertPeriodCounts(timeline, 3, 1, 3);
for (boolean shuffled : new boolean[] {false, true}) {
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_OFF, shuffled,
C.INDEX_UNSET, 0, 1);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ONE, shuffled,
2, 0, 1);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ALL, shuffled,
2, 0, 1);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_OFF, shuffled,
1, 2, C.INDEX_UNSET);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_OFF, shuffled, C.INDEX_UNSET, 0, 1);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_ONE, shuffled, 2, 0, 1);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_ALL, shuffled, 2, 0, 1);
TimelineAsserts.assertNextWindowIndices(
timeline, Player.REPEAT_MODE_OFF, shuffled, 1, 2, C.INDEX_UNSET);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ONE, shuffled, 1, 2, 0);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ALL, shuffled, 1, 2, 0);
assertThat(timeline.getFirstWindowIndex(shuffled)).isEqualTo(0);
......@@ -125,34 +132,36 @@ public final class ConcatenatingMediaSourceTest extends TestCase {
}
}
@Test
public void testNestedMediaSources() throws IOException {
Timeline timeline = getConcatenatedTimeline(false,
getConcatenatedTimeline(false, createFakeTimeline(1, 111), createFakeTimeline(1, 222)),
getConcatenatedTimeline(true, createFakeTimeline(1, 333), createFakeTimeline(1, 444)));
Timeline timeline =
getConcatenatedTimeline(
false,
getConcatenatedTimeline(false, createFakeTimeline(1, 111), createFakeTimeline(1, 222)),
getConcatenatedTimeline(true, createFakeTimeline(1, 333), createFakeTimeline(1, 444)));
TimelineAsserts.assertWindowIds(timeline, 111, 222, 333, 444);
TimelineAsserts.assertPeriodCounts(timeline, 1, 1, 1, 1);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_OFF, false,
C.INDEX_UNSET, 0, 1, 2);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ONE, false,
0, 1, 3, 2);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ALL, false,
3, 0, 1, 2);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_OFF, false,
1, 2, 3, C.INDEX_UNSET);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_OFF, false, C.INDEX_UNSET, 0, 1, 2);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_ONE, false, 0, 1, 3, 2);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_ALL, false, 3, 0, 1, 2);
TimelineAsserts.assertNextWindowIndices(
timeline, Player.REPEAT_MODE_OFF, false, 1, 2, 3, C.INDEX_UNSET);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ONE, false, 0, 1, 3, 2);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ALL, false, 1, 2, 3, 0);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_OFF, true,
1, 3, C.INDEX_UNSET, 2);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ONE, true,
0, 1, 3, 2);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ALL, true,
1, 3, 0, 2);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_OFF, true,
C.INDEX_UNSET, 0, 3, 1);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_OFF, true, 1, 3, C.INDEX_UNSET, 2);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ONE, true, 0, 1, 3, 2);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ALL, true, 1, 3, 0, 2);
TimelineAsserts.assertNextWindowIndices(
timeline, Player.REPEAT_MODE_OFF, true, C.INDEX_UNSET, 0, 3, 1);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ONE, true, 0, 1, 3, 2);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ALL, true, 2, 0, 3, 1);
}
@Test
public void testEmptyTimelineMediaSources() throws IOException {
// Empty timelines in the front, back, and the middle (single and multiple in a row).
Timeline[] timelines = {
......@@ -168,20 +177,20 @@ public final class ConcatenatingMediaSourceTest extends TestCase {
Timeline timeline = getConcatenatedTimeline(false, timelines);
TimelineAsserts.assertWindowIds(timeline, 111, 222, 333);
TimelineAsserts.assertPeriodCounts(timeline, 1, 2, 3);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_OFF, false,
C.INDEX_UNSET, 0, 1);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_OFF, false, C.INDEX_UNSET, 0, 1);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ONE, false, 0, 1, 2);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ALL, false, 2, 0, 1);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_OFF, false,
1, 2, C.INDEX_UNSET);
TimelineAsserts.assertNextWindowIndices(
timeline, Player.REPEAT_MODE_OFF, false, 1, 2, C.INDEX_UNSET);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ONE, false, 0, 1, 2);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ALL, false, 1, 2, 0);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_OFF, true,
1, 2, C.INDEX_UNSET);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_OFF, true, 1, 2, C.INDEX_UNSET);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ONE, true, 0, 1, 2);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ALL, true, 1, 2, 0);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_OFF, true,
C.INDEX_UNSET, 0, 1);
TimelineAsserts.assertNextWindowIndices(
timeline, Player.REPEAT_MODE_OFF, true, C.INDEX_UNSET, 0, 1);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ONE, true, 0, 1, 2);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ALL, true, 2, 0, 1);
assertThat(timeline.getFirstWindowIndex(false)).isEqualTo(0);
......@@ -193,14 +202,14 @@ public final class ConcatenatingMediaSourceTest extends TestCase {
TimelineAsserts.assertWindowIds(timeline, 111, 222, 333);
TimelineAsserts.assertPeriodCounts(timeline, 1, 2, 3);
for (boolean shuffled : new boolean[] {false, true}) {
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_OFF, shuffled,
C.INDEX_UNSET, 0, 1);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ONE, shuffled,
2, 0, 1);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ALL, shuffled,
2, 0, 1);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_OFF, shuffled,
1, 2, C.INDEX_UNSET);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_OFF, shuffled, C.INDEX_UNSET, 0, 1);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_ONE, shuffled, 2, 0, 1);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_ALL, shuffled, 2, 0, 1);
TimelineAsserts.assertNextWindowIndices(
timeline, Player.REPEAT_MODE_OFF, shuffled, 1, 2, C.INDEX_UNSET);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ONE, shuffled, 1, 2, 0);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ALL, shuffled, 1, 2, 0);
assertThat(timeline.getFirstWindowIndex(shuffled)).isEqualTo(0);
......@@ -208,10 +217,12 @@ public final class ConcatenatingMediaSourceTest extends TestCase {
}
}
@Test
public void testPeriodCreationWithAds() throws IOException, InterruptedException {
// Create media source with ad child source.
Timeline timelineContentOnly = new FakeTimeline(
new TimelineWindowDefinition(2, 111, true, false, 10 * C.MICROS_PER_SECOND));
Timeline timelineContentOnly =
new FakeTimeline(
new TimelineWindowDefinition(2, 111, true, false, 10 * C.MICROS_PER_SECOND));
Timeline timelineWithAds =
new FakeTimeline(
new TimelineWindowDefinition(
......@@ -224,8 +235,8 @@ public final class ConcatenatingMediaSourceTest extends TestCase {
/* adsPerAdGroup= */ 1, /* adGroupTimesUs= */ 0)));
FakeMediaSource mediaSourceContentOnly = new FakeMediaSource(timelineContentOnly, null);
FakeMediaSource mediaSourceWithAds = new FakeMediaSource(timelineWithAds, null);
ConcatenatingMediaSource mediaSource = new ConcatenatingMediaSource(mediaSourceContentOnly,
mediaSourceWithAds);
ConcatenatingMediaSource mediaSource =
new ConcatenatingMediaSource(mediaSourceContentOnly, mediaSourceWithAds);
MediaSourceTestRunner testRunner = new MediaSourceTestRunner(mediaSource, null);
try {
......@@ -246,17 +257,18 @@ public final class ConcatenatingMediaSourceTest extends TestCase {
}
/**
* Wraps the specified timelines in a {@link ConcatenatingMediaSource} and returns
* the concatenated timeline.
* Wraps the specified timelines in a {@link ConcatenatingMediaSource} and returns the
* concatenated timeline.
*/
private static Timeline getConcatenatedTimeline(boolean isRepeatOneAtomic,
Timeline... timelines) throws IOException {
private static Timeline getConcatenatedTimeline(boolean isRepeatOneAtomic, Timeline... timelines)
throws IOException {
FakeMediaSource[] mediaSources = new FakeMediaSource[timelines.length];
for (int i = 0; i < timelines.length; i++) {
mediaSources[i] = new FakeMediaSource(timelines[i], null);
}
ConcatenatingMediaSource mediaSource = new ConcatenatingMediaSource(isRepeatOneAtomic,
new FakeShuffleOrder(mediaSources.length), mediaSources);
ConcatenatingMediaSource mediaSource =
new ConcatenatingMediaSource(
isRepeatOneAtomic, new FakeShuffleOrder(mediaSources.length), mediaSources);
MediaSourceTestRunner testRunner = new MediaSourceTestRunner(mediaSource, null);
try {
Timeline timeline = testRunner.prepareSource();
......@@ -273,5 +285,4 @@ public final class ConcatenatingMediaSourceTest extends TestCase {
private static FakeTimeline createFakeTimeline(int periodCount, int windowId) {
return new FakeTimeline(new TimelineWindowDefinition(periodCount, windowId));
}
}
......@@ -16,6 +16,7 @@
package com.google.android.exoplayer2.source;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.verify;
import android.os.ConditionVariable;
......@@ -23,6 +24,7 @@ import android.os.Handler;
import android.os.HandlerThread;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.RobolectricUtil;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
import com.google.android.exoplayer2.testutil.FakeMediaSource;
......@@ -33,32 +35,37 @@ import com.google.android.exoplayer2.testutil.MediaSourceTestRunner;
import com.google.android.exoplayer2.testutil.TimelineAsserts;
import java.io.IOException;
import java.util.Arrays;
import junit.framework.TestCase;
import java.util.concurrent.CountDownLatch;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit tests for {@link DynamicConcatenatingMediaSource}
*/
public final class DynamicConcatenatingMediaSourceTest extends TestCase {
/** Unit tests for {@link DynamicConcatenatingMediaSource} */
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {RobolectricUtil.CustomLooper.class, RobolectricUtil.CustomMessageQueue.class})
public final class DynamicConcatenatingMediaSourceTest {
private DynamicConcatenatingMediaSource mediaSource;
private MediaSourceTestRunner testRunner;
@Override
@Before
public void setUp() throws Exception {
super.setUp();
mediaSource =
new DynamicConcatenatingMediaSource(/* isAtomic= */ false, new FakeShuffleOrder(0));
testRunner = new MediaSourceTestRunner(mediaSource, null);
}
@Override
@After
public void tearDown() throws Exception {
super.tearDown();
testRunner.release();
}
public void testPlaylistChangesAfterPreparation() throws IOException {
@Test
public void testPlaylistChangesAfterPreparation() throws IOException, InterruptedException {
Timeline timeline = testRunner.prepareSource();
TimelineAsserts.assertEmpty(timeline);
......@@ -89,8 +96,8 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
TimelineAsserts.assertWindowIds(timeline, 222, 444, 111, 333);
// Add bulk.
mediaSource.addMediaSources(3, Arrays.<MediaSource>asList(childSources[4], childSources[5],
childSources[6]));
mediaSource.addMediaSources(
3, Arrays.<MediaSource>asList(childSources[4], childSources[5], childSources[6]));
timeline = testRunner.assertTimelineChangeBlocking();
TimelineAsserts.assertPeriodCounts(timeline, 2, 4, 1, 5, 6, 7, 3);
TimelineAsserts.assertWindowIds(timeline, 222, 444, 111, 555, 666, 777, 333);
......@@ -129,22 +136,22 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
}
// Assert correct next and previous indices behavior after some insertions and removals.
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_OFF, false,
1, 2, C.INDEX_UNSET);
TimelineAsserts.assertNextWindowIndices(
timeline, Player.REPEAT_MODE_OFF, false, 1, 2, C.INDEX_UNSET);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ONE, false, 0, 1, 2);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ALL, false, 1, 2, 0);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_OFF, false,
C.INDEX_UNSET, 0, 1);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_OFF, false, C.INDEX_UNSET, 0, 1);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ONE, false, 0, 1, 2);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ALL, false, 2, 0, 1);
assertThat(timeline.getFirstWindowIndex(false)).isEqualTo(0);
assertThat(timeline.getLastWindowIndex(false)).isEqualTo(timeline.getWindowCount() - 1);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_OFF, true,
C.INDEX_UNSET, 0, 1);
TimelineAsserts.assertNextWindowIndices(
timeline, Player.REPEAT_MODE_OFF, true, C.INDEX_UNSET, 0, 1);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ONE, true, 0, 1, 2);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ALL, true, 2, 0, 1);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_OFF, true,
1, 2, C.INDEX_UNSET);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_OFF, true, 1, 2, C.INDEX_UNSET);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ONE, true, 0, 1, 2);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ALL, true, 1, 2, 0);
assertThat(timeline.getFirstWindowIndex(true)).isEqualTo(timeline.getWindowCount() - 1);
......@@ -174,7 +181,8 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
childSources[3].assertReleased();
}
public void testPlaylistChangesBeforePreparation() throws IOException {
@Test
public void testPlaylistChangesBeforePreparation() throws IOException, InterruptedException {
FakeMediaSource[] childSources = createMediaSources(4);
mediaSource.addMediaSource(childSources[0]);
mediaSource.addMediaSource(childSources[1]);
......@@ -188,14 +196,14 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
Timeline timeline = testRunner.prepareSource();
TimelineAsserts.assertPeriodCounts(timeline, 3, 4, 2);
TimelineAsserts.assertWindowIds(timeline, 333, 444, 222);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_OFF, false,
1, 2, C.INDEX_UNSET);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_OFF, false,
C.INDEX_UNSET, 0, 1);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_OFF, true,
C.INDEX_UNSET, 0, 1);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_OFF, true,
1, 2, C.INDEX_UNSET);
TimelineAsserts.assertNextWindowIndices(
timeline, Player.REPEAT_MODE_OFF, false, 1, 2, C.INDEX_UNSET);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_OFF, false, C.INDEX_UNSET, 0, 1);
TimelineAsserts.assertNextWindowIndices(
timeline, Player.REPEAT_MODE_OFF, true, C.INDEX_UNSET, 0, 1);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_OFF, true, 1, 2, C.INDEX_UNSET);
testRunner.assertPrepareAndReleaseAllPeriods();
mediaSource.releaseSource();
......@@ -204,7 +212,8 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
}
}
public void testPlaylistWithLazyMediaSource() throws IOException {
@Test
public void testPlaylistWithLazyMediaSource() throws IOException, InterruptedException {
// Create some normal (immediately preparing) sources and some lazy sources whose timeline
// updates need to be triggered.
FakeMediaSource[] fastSources = createMediaSources(2);
......@@ -230,12 +239,13 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
// Trigger source info refresh for lazy source and check that the timeline now contains all
// information for all windows.
testRunner.runOnPlaybackThread(new Runnable() {
@Override
public void run() {
lazySources[1].setNewSourceInfo(createFakeTimeline(8), null);
}
});
testRunner.runOnPlaybackThread(
new Runnable() {
@Override
public void run() {
lazySources[1].setNewSourceInfo(createFakeTimeline(8), null);
}
});
timeline = testRunner.assertTimelineChangeBlocking();
TimelineAsserts.assertPeriodCounts(timeline, 1, 9);
TimelineAsserts.assertWindowIds(timeline, 111, 999);
......@@ -259,8 +269,8 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
// Create a period from an unprepared lazy media source and assert Callback.onPrepared is not
// called yet.
MediaPeriod lazyPeriod = testRunner.createPeriod(new MediaPeriodId(0));
ConditionVariable preparedCondition = testRunner.preparePeriod(lazyPeriod, 0);
assertThat(preparedCondition.block(1)).isFalse();
CountDownLatch preparedCondition = testRunner.preparePeriod(lazyPeriod, 0);
assertThat(preparedCondition.getCount()).isEqualTo(1);
// Assert that a second period can also be created and released without problems.
MediaPeriod secondLazyPeriod = testRunner.createPeriod(new MediaPeriodId(0));
......@@ -268,17 +278,18 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
// Trigger source info refresh for lazy media source. Assert that now all information is
// available again and the previously created period now also finished preparing.
testRunner.runOnPlaybackThread(new Runnable() {
@Override
public void run() {
lazySources[3].setNewSourceInfo(createFakeTimeline(7), null);
}
});
testRunner.runOnPlaybackThread(
new Runnable() {
@Override
public void run() {
lazySources[3].setNewSourceInfo(createFakeTimeline(7), null);
}
});
timeline = testRunner.assertTimelineChangeBlocking();
TimelineAsserts.assertPeriodCounts(timeline, 8, 1, 2, 9);
TimelineAsserts.assertWindowIds(timeline, 888, 111, 222, 999);
TimelineAsserts.assertWindowIsDynamic(timeline, false, false, false, false);
assertThat(preparedCondition.block(1)).isTrue();
assertThat(preparedCondition.getCount()).isEqualTo(0);
// Release the period and source.
testRunner.releasePeriod(lazyPeriod);
......@@ -293,7 +304,8 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
}
}
public void testEmptyTimelineMediaSource() throws IOException {
@Test
public void testEmptyTimelineMediaSource() throws IOException, InterruptedException {
Timeline timeline = testRunner.prepareSource();
TimelineAsserts.assertEmpty(timeline);
......@@ -322,20 +334,20 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
timeline = testRunner.assertTimelineChangeBlocking();
TimelineAsserts.assertWindowIds(timeline, 111, 222, 333);
TimelineAsserts.assertPeriodCounts(timeline, 1, 2, 3);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_OFF, false,
C.INDEX_UNSET, 0, 1);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_OFF, false, C.INDEX_UNSET, 0, 1);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ONE, false, 0, 1, 2);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ALL, false, 2, 0, 1);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_OFF, false,
1, 2, C.INDEX_UNSET);
TimelineAsserts.assertNextWindowIndices(
timeline, Player.REPEAT_MODE_OFF, false, 1, 2, C.INDEX_UNSET);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ONE, false, 0, 1, 2);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ALL, false, 1, 2, 0);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_OFF, true,
1, 2, C.INDEX_UNSET);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_OFF, true, 1, 2, C.INDEX_UNSET);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ONE, true, 0, 1, 2);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ALL, true, 1, 2, 0);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_OFF, true,
C.INDEX_UNSET, 0, 1);
TimelineAsserts.assertNextWindowIndices(
timeline, Player.REPEAT_MODE_OFF, true, C.INDEX_UNSET, 0, 1);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ONE, true, 0, 1, 2);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ALL, true, 2, 0, 1);
assertThat(timeline.getFirstWindowIndex(false)).isEqualTo(0);
......@@ -345,6 +357,7 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
testRunner.assertPrepareAndReleaseAllPeriods();
}
@Test
public void testDynamicChangeOfEmptyTimelines() throws IOException {
FakeMediaSource[] childSources =
new FakeMediaSource[] {
......@@ -371,6 +384,7 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
TimelineAsserts.assertPeriodCounts(timeline, 1, 1, 1);
}
@Test
public void testIllegalArguments() {
MediaSource validSource = new FakeMediaSource(createFakeTimeline(1), null);
......@@ -382,7 +396,7 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
// Expected.
}
MediaSource[] mediaSources = { validSource, null };
MediaSource[] mediaSources = {validSource, null};
try {
mediaSource.addMediaSources(Arrays.asList(mediaSources));
fail("Null mediaSource not allowed.");
......@@ -399,8 +413,8 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
// Expected.
}
mediaSources = new MediaSource[] {
new FakeMediaSource(createFakeTimeline(2), null), validSource };
mediaSources =
new MediaSource[] {new FakeMediaSource(createFakeTimeline(2), null), validSource};
try {
mediaSource.addMediaSources(Arrays.asList(mediaSources));
fail("Duplicate mediaSource not allowed.");
......@@ -409,6 +423,7 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
}
}
@Test
public void testCustomCallbackBeforePreparationAddSingle() {
Runnable runnable = Mockito.mock(Runnable.class);
......@@ -416,14 +431,17 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
verify(runnable).run();
}
@Test
public void testCustomCallbackBeforePreparationAddMultiple() {
Runnable runnable = Mockito.mock(Runnable.class);
mediaSource.addMediaSources(Arrays.asList(
new MediaSource[] {createFakeMediaSource(), createFakeMediaSource()}), runnable);
mediaSource.addMediaSources(
Arrays.asList(new MediaSource[] {createFakeMediaSource(), createFakeMediaSource()}),
runnable);
verify(runnable).run();
}
@Test
public void testCustomCallbackBeforePreparationAddSingleWithIndex() {
Runnable runnable = Mockito.mock(Runnable.class);
......@@ -431,15 +449,18 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
verify(runnable).run();
}
@Test
public void testCustomCallbackBeforePreparationAddMultipleWithIndex() {
Runnable runnable = Mockito.mock(Runnable.class);
mediaSource.addMediaSources(/* index */ 0,
mediaSource.addMediaSources(
/* index */ 0,
Arrays.asList(new MediaSource[] {createFakeMediaSource(), createFakeMediaSource()}),
runnable);
verify(runnable).run();
}
@Test
public void testCustomCallbackBeforePreparationRemove() {
Runnable runnable = Mockito.mock(Runnable.class);
......@@ -448,6 +469,7 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
verify(runnable).run();
}
@Test
public void testCustomCallbackBeforePreparationMove() {
Runnable runnable = Mockito.mock(Runnable.class);
......@@ -457,17 +479,19 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
verify(runnable).run();
}
@Test
public void testCustomCallbackAfterPreparationAddSingle() throws IOException {
DummyMainThread dummyMainThread = new DummyMainThread();
try {
testRunner.prepareSource();
final TimelineGrabber timelineGrabber = new TimelineGrabber(testRunner);
dummyMainThread.runOnMainThread(new Runnable() {
@Override
public void run() {
mediaSource.addMediaSource(createFakeMediaSource(), timelineGrabber);
}
});
dummyMainThread.runOnMainThread(
new Runnable() {
@Override
public void run() {
mediaSource.addMediaSource(createFakeMediaSource(), timelineGrabber);
}
});
Timeline timeline = timelineGrabber.assertTimelineChangeBlocking();
assertThat(timeline.getWindowCount()).isEqualTo(1);
} finally {
......@@ -475,6 +499,7 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
}
}
@Test
public void testCustomCallbackAfterPreparationAddMultiple() throws IOException {
DummyMainThread dummyMainThread = new DummyMainThread();
try {
......@@ -497,17 +522,19 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
}
}
@Test
public void testCustomCallbackAfterPreparationAddSingleWithIndex() throws IOException {
DummyMainThread dummyMainThread = new DummyMainThread();
try {
testRunner.prepareSource();
final TimelineGrabber timelineGrabber = new TimelineGrabber(testRunner);
dummyMainThread.runOnMainThread(new Runnable() {
@Override
public void run() {
mediaSource.addMediaSource(/* index */ 0, createFakeMediaSource(), timelineGrabber);
}
});
dummyMainThread.runOnMainThread(
new Runnable() {
@Override
public void run() {
mediaSource.addMediaSource(/* index */ 0, createFakeMediaSource(), timelineGrabber);
}
});
Timeline timeline = timelineGrabber.assertTimelineChangeBlocking();
assertThat(timeline.getWindowCount()).isEqualTo(1);
} finally {
......@@ -515,6 +542,7 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
}
}
@Test
public void testCustomCallbackAfterPreparationAddMultipleWithIndex() throws IOException {
DummyMainThread dummyMainThread = new DummyMainThread();
try {
......@@ -538,25 +566,28 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
}
}
@Test
public void testCustomCallbackAfterPreparationRemove() throws IOException {
DummyMainThread dummyMainThread = new DummyMainThread();
try {
testRunner.prepareSource();
dummyMainThread.runOnMainThread(new Runnable() {
@Override
public void run() {
mediaSource.addMediaSource(createFakeMediaSource());
}
});
dummyMainThread.runOnMainThread(
new Runnable() {
@Override
public void run() {
mediaSource.addMediaSource(createFakeMediaSource());
}
});
testRunner.assertTimelineChangeBlocking();
final TimelineGrabber timelineGrabber = new TimelineGrabber(testRunner);
dummyMainThread.runOnMainThread(new Runnable() {
@Override
public void run() {
mediaSource.removeMediaSource(/* index */ 0, timelineGrabber);
}
});
dummyMainThread.runOnMainThread(
new Runnable() {
@Override
public void run() {
mediaSource.removeMediaSource(/* index */ 0, timelineGrabber);
}
});
Timeline timeline = timelineGrabber.assertTimelineChangeBlocking();
assertThat(timeline.getWindowCount()).isEqualTo(0);
} finally {
......@@ -564,6 +595,7 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
}
}
@Test
public void testCustomCallbackAfterPreparationMove() throws IOException {
DummyMainThread dummyMainThread = new DummyMainThread();
try {
......@@ -580,13 +612,13 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
testRunner.assertTimelineChangeBlocking();
final TimelineGrabber timelineGrabber = new TimelineGrabber(testRunner);
dummyMainThread.runOnMainThread(new Runnable() {
@Override
public void run() {
mediaSource.moveMediaSource(/* fromIndex */ 1, /* toIndex */ 0,
timelineGrabber);
}
});
dummyMainThread.runOnMainThread(
new Runnable() {
@Override
public void run() {
mediaSource.moveMediaSource(/* fromIndex */ 1, /* toIndex */ 0, timelineGrabber);
}
});
Timeline timeline = timelineGrabber.assertTimelineChangeBlocking();
assertThat(timeline.getWindowCount()).isEqualTo(2);
} finally {
......@@ -594,10 +626,12 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
}
}
@Test
public void testPeriodCreationWithAds() throws IOException, InterruptedException {
// Create dynamic media source with ad child source.
Timeline timelineContentOnly = new FakeTimeline(
new TimelineWindowDefinition(2, 111, true, false, 10 * C.MICROS_PER_SECOND));
Timeline timelineContentOnly =
new FakeTimeline(
new TimelineWindowDefinition(2, 111, true, false, 10 * C.MICROS_PER_SECOND));
Timeline timelineWithAds =
new FakeTimeline(
new TimelineWindowDefinition(
......@@ -628,6 +662,7 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
mediaSourceWithAds.assertMediaPeriodCreated(new MediaPeriodId(1, 0, 0));
}
@Test
public void testAtomicTimelineWindowOrder() throws IOException {
// Release default test runner with non-atomic media source and replace with new test runner.
testRunner.release();
......@@ -668,6 +703,7 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
assertThat(timeline.getLastWindowIndex(/* shuffleModeEnabled= */ true)).isEqualTo(2);
}
@Test
public void testNestedTimeline() throws IOException {
DynamicConcatenatingMediaSource nestedSource1 =
new DynamicConcatenatingMediaSource(/* isAtomic= */ false, new FakeShuffleOrder(0));
......@@ -714,6 +750,7 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
timeline, Player.REPEAT_MODE_ALL, /* shuffleModeEnabled= */ true, 2, 0, 3, 1);
}
@Test
public void testRemoveChildSourceWithActiveMediaPeriod() throws IOException {
FakeMediaSource childSource = createFakeMediaSource();
mediaSource.addMediaSource(childSource);
......@@ -760,20 +797,20 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
*/
public void runOnMainThread(final Runnable runnable) {
final ConditionVariable finishedCondition = new ConditionVariable();
handler.post(new Runnable() {
@Override
public void run() {
runnable.run();
finishedCondition.open();
}
});
handler.post(
new Runnable() {
@Override
public void run() {
runnable.run();
finishedCondition.open();
}
});
assertThat(finishedCondition.block(MediaSourceTestRunner.TIMEOUT_MS)).isTrue();
}
public void release() {
thread.quit();
}
}
private static final class TimelineGrabber implements Runnable {
......@@ -806,7 +843,5 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
}
return timeline;
}
}
}
......@@ -17,6 +17,7 @@ package com.google.android.exoplayer2.source;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.RobolectricUtil;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.testutil.FakeMediaSource;
import com.google.android.exoplayer2.testutil.FakeTimeline;
......@@ -24,77 +25,87 @@ import com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinit
import com.google.android.exoplayer2.testutil.MediaSourceTestRunner;
import com.google.android.exoplayer2.testutil.TimelineAsserts;
import java.io.IOException;
import junit.framework.TestCase;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit tests for {@link LoopingMediaSource}.
*/
public class LoopingMediaSourceTest extends TestCase {
/** Unit tests for {@link LoopingMediaSource}. */
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {RobolectricUtil.CustomLooper.class, RobolectricUtil.CustomMessageQueue.class})
public class LoopingMediaSourceTest {
private FakeTimeline multiWindowTimeline;
@Override
@Before
public void setUp() throws Exception {
super.setUp();
multiWindowTimeline = new FakeTimeline(new TimelineWindowDefinition(1, 111),
new TimelineWindowDefinition(1, 222), new TimelineWindowDefinition(1, 333));
multiWindowTimeline =
new FakeTimeline(
new TimelineWindowDefinition(1, 111),
new TimelineWindowDefinition(1, 222),
new TimelineWindowDefinition(1, 333));
}
@Test
public void testSingleLoop() throws IOException {
Timeline timeline = getLoopingTimeline(multiWindowTimeline, 1);
TimelineAsserts.assertWindowIds(timeline, 111, 222, 333);
TimelineAsserts.assertPeriodCounts(timeline, 1, 1, 1);
for (boolean shuffled : new boolean[] {false, true}) {
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_OFF, shuffled,
C.INDEX_UNSET, 0, 1);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ONE, shuffled,
0, 1, 2);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ALL, shuffled,
2, 0, 1);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_OFF, shuffled,
1, 2, C.INDEX_UNSET);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_OFF, shuffled, C.INDEX_UNSET, 0, 1);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_ONE, shuffled, 0, 1, 2);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_ALL, shuffled, 2, 0, 1);
TimelineAsserts.assertNextWindowIndices(
timeline, Player.REPEAT_MODE_OFF, shuffled, 1, 2, C.INDEX_UNSET);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ONE, shuffled, 0, 1, 2);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ALL, shuffled, 1, 2, 0);
}
}
@Test
public void testMultiLoop() throws IOException {
Timeline timeline = getLoopingTimeline(multiWindowTimeline, 3);
TimelineAsserts.assertWindowIds(timeline, 111, 222, 333, 111, 222, 333, 111, 222, 333);
TimelineAsserts.assertPeriodCounts(timeline, 1, 1, 1, 1, 1, 1, 1, 1, 1);
for (boolean shuffled : new boolean[] {false, true}) {
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_OFF, shuffled,
C.INDEX_UNSET, 0, 1, 2, 3, 4, 5, 6, 7, 8);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ONE, shuffled,
0, 1, 2, 3, 4, 5, 6, 7, 8);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ALL, shuffled,
8, 0, 1, 2, 3, 4, 5, 6, 7);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_OFF, shuffled,
1, 2, 3, 4, 5, 6, 7, 8, C.INDEX_UNSET);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ONE, shuffled,
0, 1, 2, 3, 4, 5, 6, 7, 8);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ALL, shuffled,
1, 2, 3, 4, 5, 6, 7, 8, 0);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_OFF, shuffled, C.INDEX_UNSET, 0, 1, 2, 3, 4, 5, 6, 7, 8);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_ONE, shuffled, 0, 1, 2, 3, 4, 5, 6, 7, 8);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_ALL, shuffled, 8, 0, 1, 2, 3, 4, 5, 6, 7);
TimelineAsserts.assertNextWindowIndices(
timeline, Player.REPEAT_MODE_OFF, shuffled, 1, 2, 3, 4, 5, 6, 7, 8, C.INDEX_UNSET);
TimelineAsserts.assertNextWindowIndices(
timeline, Player.REPEAT_MODE_ONE, shuffled, 0, 1, 2, 3, 4, 5, 6, 7, 8);
TimelineAsserts.assertNextWindowIndices(
timeline, Player.REPEAT_MODE_ALL, shuffled, 1, 2, 3, 4, 5, 6, 7, 8, 0);
}
}
@Test
public void testInfiniteLoop() throws IOException {
Timeline timeline = getLoopingTimeline(multiWindowTimeline, Integer.MAX_VALUE);
TimelineAsserts.assertWindowIds(timeline, 111, 222, 333);
TimelineAsserts.assertPeriodCounts(timeline, 1, 1, 1);
for (boolean shuffled : new boolean[] {false, true}) {
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_OFF, shuffled,
2, 0, 1);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ONE, shuffled,
0, 1, 2);
TimelineAsserts.assertPreviousWindowIndices(timeline, Player.REPEAT_MODE_ALL, shuffled,
2, 0, 1);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_OFF, shuffled, 2, 0, 1);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_ONE, shuffled, 0, 1, 2);
TimelineAsserts.assertPreviousWindowIndices(
timeline, Player.REPEAT_MODE_ALL, shuffled, 2, 0, 1);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_OFF, shuffled, 1, 2, 0);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ONE, shuffled, 0, 1, 2);
TimelineAsserts.assertNextWindowIndices(timeline, Player.REPEAT_MODE_ALL, shuffled, 1, 2, 0);
}
}
@Test
public void testEmptyTimelineLoop() throws IOException {
Timeline timeline = getLoopingTimeline(Timeline.EMPTY, 1);
TimelineAsserts.assertEmpty(timeline);
......@@ -107,8 +118,7 @@ public class LoopingMediaSourceTest extends TestCase {
}
/**
* Wraps the specified timeline in a {@link LoopingMediaSource} and returns
* the looping timeline.
* Wraps the specified timeline in a {@link LoopingMediaSource} and returns the looping timeline.
*/
private static Timeline getLoopingTimeline(Timeline timeline, int loopCount) throws IOException {
FakeMediaSource fakeMediaSource = new FakeMediaSource(timeline, null);
......@@ -123,5 +133,4 @@ public class LoopingMediaSourceTest extends TestCase {
testRunner.release();
}
}
}
......@@ -16,8 +16,10 @@
package com.google.android.exoplayer2.source;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.RobolectricUtil;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.source.MergingMediaSource.IllegalMergeException;
import com.google.android.exoplayer2.testutil.FakeMediaSource;
......@@ -25,29 +27,33 @@ import com.google.android.exoplayer2.testutil.FakeTimeline;
import com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinition;
import com.google.android.exoplayer2.testutil.MediaSourceTestRunner;
import java.io.IOException;
import junit.framework.TestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit tests for {@link MergingMediaSource}.
*/
public class MergingMediaSourceTest extends TestCase {
/** Unit tests for {@link MergingMediaSource}. */
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {RobolectricUtil.CustomLooper.class, RobolectricUtil.CustomMessageQueue.class})
public class MergingMediaSourceTest {
@Test
public void testMergingDynamicTimelines() throws IOException {
FakeTimeline firstTimeline = new FakeTimeline(
new TimelineWindowDefinition(true, true, C.TIME_UNSET));
FakeTimeline secondTimeline = new FakeTimeline(
new TimelineWindowDefinition(true, true, C.TIME_UNSET));
FakeTimeline firstTimeline =
new FakeTimeline(new TimelineWindowDefinition(true, true, C.TIME_UNSET));
FakeTimeline secondTimeline =
new FakeTimeline(new TimelineWindowDefinition(true, true, C.TIME_UNSET));
testMergingMediaSourcePrepare(firstTimeline, secondTimeline);
}
@Test
public void testMergingStaticTimelines() throws IOException {
FakeTimeline firstTimeline = new FakeTimeline(
new TimelineWindowDefinition(true, false, 20));
FakeTimeline secondTimeline = new FakeTimeline(
new TimelineWindowDefinition(true, false, 10));
FakeTimeline firstTimeline = new FakeTimeline(new TimelineWindowDefinition(true, false, 20));
FakeTimeline secondTimeline = new FakeTimeline(new TimelineWindowDefinition(true, false, 10));
testMergingMediaSourcePrepare(firstTimeline, secondTimeline);
}
@Test
public void testMergingTimelinesWithDifferentPeriodCounts() throws IOException {
FakeTimeline firstTimeline = new FakeTimeline(new TimelineWindowDefinition(1, null));
FakeTimeline secondTimeline = new FakeTimeline(new TimelineWindowDefinition(2, null));
......@@ -82,5 +88,4 @@ public class MergingMediaSourceTest extends TestCase {
testRunner.release();
}
}
}
......@@ -36,13 +36,11 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Test for {@link SampleQueue}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class SampleQueueTest {
private static final int ALLOCATION_SIZE = 16;
......
......@@ -24,13 +24,11 @@ import com.google.android.exoplayer2.source.ShuffleOrder.UnshuffledShuffleOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit test for {@link ShuffleOrder}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class ShuffleOrderTest {
public static final long RANDOM_SEED = 1234567890L;
......
......@@ -25,13 +25,11 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit test for {@link SinglePeriodTimeline}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class SinglePeriodTimelineTest {
private Window window;
......
......@@ -24,11 +24,9 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/** Unit test for {@link AdPlaybackState}. */
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class AdPlaybackStateTest {
private static final long[] TEST_AD_GROUP_TMES_US = new long[] {0, C.msToUs(10_000)};
......
......@@ -17,15 +17,17 @@ package com.google.android.exoplayer2.text.ssa;
import static com.google.common.truth.Truth.assertThat;
import android.test.InstrumentationTestCase;
import com.google.android.exoplayer2.testutil.TestUtil;
import java.io.IOException;
import java.util.ArrayList;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
/**
* Unit test for {@link SsaDecoder}.
*/
public final class SsaDecoderTest extends InstrumentationTestCase {
/** Unit test for {@link SsaDecoder}. */
@RunWith(RobolectricTestRunner.class)
public final class SsaDecoderTest {
private static final String EMPTY = "ssa/empty";
private static final String TYPICAL = "ssa/typical";
......@@ -35,18 +37,20 @@ public final class SsaDecoderTest extends InstrumentationTestCase {
private static final String INVALID_TIMECODES = "ssa/invalid_timecodes";
private static final String NO_END_TIMECODES = "ssa/no_end_timecodes";
@Test
public void testDecodeEmpty() throws IOException {
SsaDecoder decoder = new SsaDecoder();
byte[] bytes = TestUtil.getByteArray(getInstrumentation(), EMPTY);
byte[] bytes = TestUtil.getByteArray(RuntimeEnvironment.application, EMPTY);
SsaSubtitle subtitle = decoder.decode(bytes, bytes.length, false);
assertThat(subtitle.getEventTimeCount()).isEqualTo(0);
assertThat(subtitle.getCues(0).isEmpty()).isTrue();
}
@Test
public void testDecodeTypical() throws IOException {
SsaDecoder decoder = new SsaDecoder();
byte[] bytes = TestUtil.getByteArray(getInstrumentation(), TYPICAL);
byte[] bytes = TestUtil.getByteArray(RuntimeEnvironment.application, TYPICAL);
SsaSubtitle subtitle = decoder.decode(bytes, bytes.length, false);
assertThat(subtitle.getEventTimeCount()).isEqualTo(6);
......@@ -55,14 +59,15 @@ public final class SsaDecoderTest extends InstrumentationTestCase {
assertTypicalCue3(subtitle, 4);
}
@Test
public void testDecodeTypicalWithInitializationData() throws IOException {
byte[] headerBytes = TestUtil.getByteArray(getInstrumentation(), TYPICAL_HEADER_ONLY);
byte[] formatBytes = TestUtil.getByteArray(getInstrumentation(), TYPICAL_FORMAT_ONLY);
byte[] headerBytes = TestUtil.getByteArray(RuntimeEnvironment.application, TYPICAL_HEADER_ONLY);
byte[] formatBytes = TestUtil.getByteArray(RuntimeEnvironment.application, TYPICAL_FORMAT_ONLY);
ArrayList<byte[]> initializationData = new ArrayList<>();
initializationData.add(formatBytes);
initializationData.add(headerBytes);
SsaDecoder decoder = new SsaDecoder(initializationData);
byte[] bytes = TestUtil.getByteArray(getInstrumentation(), TYPICAL_DIALOGUE_ONLY);
byte[] bytes = TestUtil.getByteArray(RuntimeEnvironment.application, TYPICAL_DIALOGUE_ONLY);
SsaSubtitle subtitle = decoder.decode(bytes, bytes.length, false);
assertThat(subtitle.getEventTimeCount()).isEqualTo(6);
......@@ -71,19 +76,21 @@ public final class SsaDecoderTest extends InstrumentationTestCase {
assertTypicalCue3(subtitle, 4);
}
@Test
public void testDecodeInvalidTimecodes() throws IOException {
// Parsing should succeed, parsing the third cue only.
SsaDecoder decoder = new SsaDecoder();
byte[] bytes = TestUtil.getByteArray(getInstrumentation(), INVALID_TIMECODES);
byte[] bytes = TestUtil.getByteArray(RuntimeEnvironment.application, INVALID_TIMECODES);
SsaSubtitle subtitle = decoder.decode(bytes, bytes.length, false);
assertThat(subtitle.getEventTimeCount()).isEqualTo(2);
assertTypicalCue3(subtitle, 0);
}
@Test
public void testDecodeNoEndTimecodes() throws IOException {
SsaDecoder decoder = new SsaDecoder();
byte[] bytes = TestUtil.getByteArray(getInstrumentation(), NO_END_TIMECODES);
byte[] bytes = TestUtil.getByteArray(RuntimeEnvironment.application, NO_END_TIMECODES);
SsaSubtitle subtitle = decoder.decode(bytes, bytes.length, false);
assertThat(subtitle.getEventTimeCount()).isEqualTo(3);
......@@ -121,5 +128,4 @@ public final class SsaDecoderTest extends InstrumentationTestCase {
.isEqualTo("This is the third subtitle, with a comma.");
assertThat(subtitle.getEventTime(eventIndex + 1)).isEqualTo(8900000);
}
}
......@@ -17,14 +17,16 @@ package com.google.android.exoplayer2.text.subrip;
import static com.google.common.truth.Truth.assertThat;
import android.test.InstrumentationTestCase;
import com.google.android.exoplayer2.testutil.TestUtil;
import java.io.IOException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
/**
* Unit test for {@link SubripDecoder}.
*/
public final class SubripDecoderTest extends InstrumentationTestCase {
/** Unit test for {@link SubripDecoder}. */
@RunWith(RobolectricTestRunner.class)
public final class SubripDecoderTest {
private static final String EMPTY_FILE = "subrip/empty";
private static final String TYPICAL_FILE = "subrip/typical";
......@@ -36,18 +38,20 @@ public final class SubripDecoderTest extends InstrumentationTestCase {
private static final String TYPICAL_UNEXPECTED_END = "subrip/typical_unexpected_end";
private static final String NO_END_TIMECODES_FILE = "subrip/no_end_timecodes";
@Test
public void testDecodeEmpty() throws IOException {
SubripDecoder decoder = new SubripDecoder();
byte[] bytes = TestUtil.getByteArray(getInstrumentation(), EMPTY_FILE);
byte[] bytes = TestUtil.getByteArray(RuntimeEnvironment.application, EMPTY_FILE);
SubripSubtitle subtitle = decoder.decode(bytes, bytes.length, false);
assertThat(subtitle.getEventTimeCount()).isEqualTo(0);
assertThat(subtitle.getCues(0).isEmpty()).isTrue();
}
@Test
public void testDecodeTypical() throws IOException {
SubripDecoder decoder = new SubripDecoder();
byte[] bytes = TestUtil.getByteArray(getInstrumentation(), TYPICAL_FILE);
byte[] bytes = TestUtil.getByteArray(RuntimeEnvironment.application, TYPICAL_FILE);
SubripSubtitle subtitle = decoder.decode(bytes, bytes.length, false);
assertThat(subtitle.getEventTimeCount()).isEqualTo(6);
......@@ -56,9 +60,11 @@ public final class SubripDecoderTest extends InstrumentationTestCase {
assertTypicalCue3(subtitle, 4);
}
@Test
public void testDecodeTypicalWithByteOrderMark() throws IOException {
SubripDecoder decoder = new SubripDecoder();
byte[] bytes = TestUtil.getByteArray(getInstrumentation(), TYPICAL_WITH_BYTE_ORDER_MARK);
byte[] bytes =
TestUtil.getByteArray(RuntimeEnvironment.application, TYPICAL_WITH_BYTE_ORDER_MARK);
SubripSubtitle subtitle = decoder.decode(bytes, bytes.length, false);
assertThat(subtitle.getEventTimeCount()).isEqualTo(6);
......@@ -67,9 +73,10 @@ public final class SubripDecoderTest extends InstrumentationTestCase {
assertTypicalCue3(subtitle, 4);
}
@Test
public void testDecodeTypicalExtraBlankLine() throws IOException {
SubripDecoder decoder = new SubripDecoder();
byte[] bytes = TestUtil.getByteArray(getInstrumentation(), TYPICAL_EXTRA_BLANK_LINE);
byte[] bytes = TestUtil.getByteArray(RuntimeEnvironment.application, TYPICAL_EXTRA_BLANK_LINE);
SubripSubtitle subtitle = decoder.decode(bytes, bytes.length, false);
assertThat(subtitle.getEventTimeCount()).isEqualTo(6);
......@@ -78,10 +85,11 @@ public final class SubripDecoderTest extends InstrumentationTestCase {
assertTypicalCue3(subtitle, 4);
}
@Test
public void testDecodeTypicalMissingTimecode() throws IOException {
// Parsing should succeed, parsing the first and third cues only.
SubripDecoder decoder = new SubripDecoder();
byte[] bytes = TestUtil.getByteArray(getInstrumentation(), TYPICAL_MISSING_TIMECODE);
byte[] bytes = TestUtil.getByteArray(RuntimeEnvironment.application, TYPICAL_MISSING_TIMECODE);
SubripSubtitle subtitle = decoder.decode(bytes, bytes.length, false);
assertThat(subtitle.getEventTimeCount()).isEqualTo(4);
......@@ -89,10 +97,11 @@ public final class SubripDecoderTest extends InstrumentationTestCase {
assertTypicalCue3(subtitle, 2);
}
@Test
public void testDecodeTypicalMissingSequence() throws IOException {
// Parsing should succeed, parsing the first and third cues only.
SubripDecoder decoder = new SubripDecoder();
byte[] bytes = TestUtil.getByteArray(getInstrumentation(), TYPICAL_MISSING_SEQUENCE);
byte[] bytes = TestUtil.getByteArray(RuntimeEnvironment.application, TYPICAL_MISSING_SEQUENCE);
SubripSubtitle subtitle = decoder.decode(bytes, bytes.length, false);
assertThat(subtitle.getEventTimeCount()).isEqualTo(4);
......@@ -100,20 +109,23 @@ public final class SubripDecoderTest extends InstrumentationTestCase {
assertTypicalCue3(subtitle, 2);
}
@Test
public void testDecodeTypicalNegativeTimestamps() throws IOException {
// Parsing should succeed, parsing the third cue only.
SubripDecoder decoder = new SubripDecoder();
byte[] bytes = TestUtil.getByteArray(getInstrumentation(), TYPICAL_NEGATIVE_TIMESTAMPS);
byte[] bytes =
TestUtil.getByteArray(RuntimeEnvironment.application, TYPICAL_NEGATIVE_TIMESTAMPS);
SubripSubtitle subtitle = decoder.decode(bytes, bytes.length, false);
assertThat(subtitle.getEventTimeCount()).isEqualTo(2);
assertTypicalCue3(subtitle, 0);
}
@Test
public void testDecodeTypicalUnexpectedEnd() throws IOException {
// Parsing should succeed, parsing the first and second cues only.
SubripDecoder decoder = new SubripDecoder();
byte[] bytes = TestUtil.getByteArray(getInstrumentation(), TYPICAL_UNEXPECTED_END);
byte[] bytes = TestUtil.getByteArray(RuntimeEnvironment.application, TYPICAL_UNEXPECTED_END);
SubripSubtitle subtitle = decoder.decode(bytes, bytes.length, false);
assertThat(subtitle.getEventTimeCount()).isEqualTo(4);
......@@ -121,9 +133,10 @@ public final class SubripDecoderTest extends InstrumentationTestCase {
assertTypicalCue2(subtitle, 2);
}
@Test
public void testDecodeNoEndTimecodes() throws IOException {
SubripDecoder decoder = new SubripDecoder();
byte[] bytes = TestUtil.getByteArray(getInstrumentation(), NO_END_TIMECODES_FILE);
byte[] bytes = TestUtil.getByteArray(RuntimeEnvironment.application, NO_END_TIMECODES_FILE);
SubripSubtitle subtitle = decoder.decode(bytes, bytes.length, false);
assertThat(subtitle.getEventTimeCount()).isEqualTo(3);
......@@ -161,5 +174,4 @@ public final class SubripDecoderTest extends InstrumentationTestCase {
.isEqualTo("This is the third subtitle.");
assertThat(subtitle.getEventTime(eventIndex + 1)).isEqualTo(8901000);
}
}
......@@ -18,7 +18,6 @@ package com.google.android.exoplayer2.text.ttml;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import android.test.InstrumentationTestCase;
import android.text.Layout;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
......@@ -38,11 +37,14 @@ import com.google.android.exoplayer2.util.ColorParser;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
/**
* Unit test for {@link TtmlDecoder}.
*/
public final class TtmlDecoderTest extends InstrumentationTestCase {
/** Unit test for {@link TtmlDecoder}. */
@RunWith(RobolectricTestRunner.class)
public final class TtmlDecoderTest {
private static final String INLINE_ATTRIBUTES_TTML_FILE = "ttml/inline_style_attributes.xml";
private static final String INHERIT_STYLE_TTML_FILE = "ttml/inherit_style.xml";
......@@ -62,6 +64,7 @@ public final class TtmlDecoderTest extends InstrumentationTestCase {
private static final String FONT_SIZE_EMPTY_TTML_FILE = "ttml/font_size_empty.xml";
private static final String FRAME_RATE_TTML_FILE = "ttml/frame_rate.xml";
@Test
public void testInlineAttributes() throws IOException, SubtitleDecoderException {
TtmlSubtitle subtitle = getSubtitle(INLINE_ATTRIBUTES_TTML_FILE);
assertThat(subtitle.getEventTimeCount()).isEqualTo(4);
......@@ -78,82 +81,182 @@ public final class TtmlDecoderTest extends InstrumentationTestCase {
assertThat(firstPStyle.isUnderline()).isTrue();
}
@Test
public void testInheritInlineAttributes() throws IOException, SubtitleDecoderException {
TtmlSubtitle subtitle = getSubtitle(INLINE_ATTRIBUTES_TTML_FILE);
assertThat(subtitle.getEventTimeCount()).isEqualTo(4);
assertSpans(subtitle, 20, "text 2", "sansSerif", TtmlStyle.STYLE_ITALIC,
0xFF00FFFF, ColorParser.parseTtmlColor("lime"), false, true, null);
assertSpans(
subtitle,
20,
"text 2",
"sansSerif",
TtmlStyle.STYLE_ITALIC,
0xFF00FFFF,
ColorParser.parseTtmlColor("lime"),
false,
true,
null);
}
/**
* Regression test for devices on JellyBean where some named colors are not correctly defined
* on framework level. Tests that <i>lime</i> resolves to <code>#FF00FF00</code> not
* <code>#00FF00</code>.
* Regression test for devices on JellyBean where some named colors are not correctly defined on
* framework level. Tests that <i>lime</i> resolves to <code>#FF00FF00</code> not <code>#00FF00
* </code>.
*
* @see <a href="https://github.com/android/platform_frameworks_base/blob/jb-mr2-release/graphics/java/android/graphics/Color.java#L414">
* JellyBean Color</a>
* <a href="https://github.com/android/platform_frameworks_base/blob/kitkat-mr2.2-release/graphics/java/android/graphics/Color.java#L414">
* @see <a
* href="https://github.com/android/platform_frameworks_base/blob/jb-mr2-release/graphics/java/android/graphics/Color.java#L414">
* JellyBean Color</a> <a
* href="https://github.com/android/platform_frameworks_base/blob/kitkat-mr2.2-release/graphics/java/android/graphics/Color.java#L414">
* Kitkat Color</a>
* @throws IOException thrown if reading subtitle file fails.
*/
@Test
public void testLime() throws IOException, SubtitleDecoderException {
TtmlSubtitle subtitle = getSubtitle(INLINE_ATTRIBUTES_TTML_FILE);
assertThat(subtitle.getEventTimeCount()).isEqualTo(4);
assertSpans(subtitle, 20, "text 2", "sansSerif", TtmlStyle.STYLE_ITALIC, 0xFF00FFFF, 0xFF00FF00,
false, true, null);
}
assertSpans(
subtitle,
20,
"text 2",
"sansSerif",
TtmlStyle.STYLE_ITALIC,
0xFF00FFFF,
0xFF00FF00,
false,
true,
null);
}
@Test
public void testInheritGlobalStyle() throws IOException, SubtitleDecoderException {
TtmlSubtitle subtitle = getSubtitle(INHERIT_STYLE_TTML_FILE);
assertThat(subtitle.getEventTimeCount()).isEqualTo(2);
assertSpans(subtitle, 10, "text 1", "serif", TtmlStyle.STYLE_BOLD_ITALIC, 0xFF0000FF,
0xFFFFFF00, true, false, null);
}
public void testInheritGlobalStyleOverriddenByInlineAttributes() throws IOException,
SubtitleDecoderException {
assertSpans(
subtitle,
10,
"text 1",
"serif",
TtmlStyle.STYLE_BOLD_ITALIC,
0xFF0000FF,
0xFFFFFF00,
true,
false,
null);
}
@Test
public void testInheritGlobalStyleOverriddenByInlineAttributes()
throws IOException, SubtitleDecoderException {
TtmlSubtitle subtitle = getSubtitle(INHERIT_STYLE_OVERRIDE_TTML_FILE);
assertThat(subtitle.getEventTimeCount()).isEqualTo(4);
assertSpans(subtitle, 10, "text 1", "serif", TtmlStyle.STYLE_BOLD_ITALIC, 0xFF0000FF,
0xFFFFFF00, true, false, null);
assertSpans(subtitle, 20, "text 2", "sansSerif", TtmlStyle.STYLE_ITALIC, 0xFFFF0000, 0xFFFFFF00,
true, false, null);
}
assertSpans(
subtitle,
10,
"text 1",
"serif",
TtmlStyle.STYLE_BOLD_ITALIC,
0xFF0000FF,
0xFFFFFF00,
true,
false,
null);
assertSpans(
subtitle,
20,
"text 2",
"sansSerif",
TtmlStyle.STYLE_ITALIC,
0xFFFF0000,
0xFFFFFF00,
true,
false,
null);
}
@Test
public void testInheritGlobalAndParent() throws IOException, SubtitleDecoderException {
TtmlSubtitle subtitle = getSubtitle(INHERIT_GLOBAL_AND_PARENT_TTML_FILE);
assertThat(subtitle.getEventTimeCount()).isEqualTo(4);
assertSpans(subtitle, 10, "text 1", "sansSerif", TtmlStyle.STYLE_NORMAL, 0xFFFF0000,
ColorParser.parseTtmlColor("lime"), false, true, Layout.Alignment.ALIGN_CENTER);
assertSpans(subtitle, 20, "text 2", "serif", TtmlStyle.STYLE_BOLD_ITALIC, 0xFF0000FF,
0xFFFFFF00, true, true, Layout.Alignment.ALIGN_CENTER);
}
assertSpans(
subtitle,
10,
"text 1",
"sansSerif",
TtmlStyle.STYLE_NORMAL,
0xFFFF0000,
ColorParser.parseTtmlColor("lime"),
false,
true,
Layout.Alignment.ALIGN_CENTER);
assertSpans(
subtitle,
20,
"text 2",
"serif",
TtmlStyle.STYLE_BOLD_ITALIC,
0xFF0000FF,
0xFFFFFF00,
true,
true,
Layout.Alignment.ALIGN_CENTER);
}
@Test
public void testInheritMultipleStyles() throws IOException, SubtitleDecoderException {
TtmlSubtitle subtitle = getSubtitle(INHERIT_MULTIPLE_STYLES_TTML_FILE);
assertThat(subtitle.getEventTimeCount()).isEqualTo(12);
assertSpans(subtitle, 10, "text 1", "sansSerif", TtmlStyle.STYLE_BOLD_ITALIC, 0xFF0000FF,
0xFFFFFF00, false, true, null);
}
public void testInheritMultipleStylesWithoutLocalAttributes() throws IOException,
SubtitleDecoderException {
assertSpans(
subtitle,
10,
"text 1",
"sansSerif",
TtmlStyle.STYLE_BOLD_ITALIC,
0xFF0000FF,
0xFFFFFF00,
false,
true,
null);
}
@Test
public void testInheritMultipleStylesWithoutLocalAttributes()
throws IOException, SubtitleDecoderException {
TtmlSubtitle subtitle = getSubtitle(INHERIT_MULTIPLE_STYLES_TTML_FILE);
assertThat(subtitle.getEventTimeCount()).isEqualTo(12);
assertSpans(subtitle, 20, "text 2", "sansSerif", TtmlStyle.STYLE_BOLD_ITALIC, 0xFF0000FF,
0xFF000000, false, true, null);
}
public void testMergeMultipleStylesWithParentStyle() throws IOException,
SubtitleDecoderException {
assertSpans(
subtitle,
20,
"text 2",
"sansSerif",
TtmlStyle.STYLE_BOLD_ITALIC,
0xFF0000FF,
0xFF000000,
false,
true,
null);
}
@Test
public void testMergeMultipleStylesWithParentStyle()
throws IOException, SubtitleDecoderException {
TtmlSubtitle subtitle = getSubtitle(INHERIT_MULTIPLE_STYLES_TTML_FILE);
assertThat(subtitle.getEventTimeCount()).isEqualTo(12);
assertSpans(subtitle, 30, "text 2.5", "sansSerifInline", TtmlStyle.STYLE_ITALIC, 0xFFFF0000,
0xFFFFFF00, true, true, null);
}
assertSpans(
subtitle,
30,
"text 2.5",
"sansSerifInline",
TtmlStyle.STYLE_ITALIC,
0xFFFF0000,
0xFFFFFF00,
true,
true,
null);
}
@Test
public void testMultipleRegions() throws IOException, SubtitleDecoderException {
TtmlSubtitle subtitle = getSubtitle(MULTIPLE_REGIONS_TTML_FILE);
List<Cue> output = subtitle.getCues(1000000);
......@@ -208,6 +311,7 @@ public final class TtmlDecoderTest extends InstrumentationTestCase {
assertThat(ttmlCue.line).isEqualTo(45f / 100f);
}
@Test
public void testEmptyStyleAttribute() throws IOException, SubtitleDecoderException {
TtmlSubtitle subtitle = getSubtitle(INHERIT_MULTIPLE_STYLES_TTML_FILE);
assertThat(subtitle.getEventTimeCount()).isEqualTo(12);
......@@ -219,6 +323,7 @@ public final class TtmlDecoderTest extends InstrumentationTestCase {
assertThat(queryChildrenForTag(fourthDiv, TtmlNode.TAG_P, 0).getStyleIds()).isNull();
}
@Test
public void testNonexistingStyleId() throws IOException, SubtitleDecoderException {
TtmlSubtitle subtitle = getSubtitle(INHERIT_MULTIPLE_STYLES_TTML_FILE);
assertThat(subtitle.getEventTimeCount()).isEqualTo(12);
......@@ -230,8 +335,9 @@ public final class TtmlDecoderTest extends InstrumentationTestCase {
assertThat(queryChildrenForTag(fifthDiv, TtmlNode.TAG_P, 0).getStyleIds()).hasLength(1);
}
public void testNonExistingAndExistingStyleIdWithRedundantSpaces() throws IOException,
SubtitleDecoderException {
@Test
public void testNonExistingAndExistingStyleIdWithRedundantSpaces()
throws IOException, SubtitleDecoderException {
TtmlSubtitle subtitle = getSubtitle(INHERIT_MULTIPLE_STYLES_TTML_FILE);
assertThat(subtitle.getEventTimeCount()).isEqualTo(12);
......@@ -243,6 +349,7 @@ public final class TtmlDecoderTest extends InstrumentationTestCase {
assertThat(styleIds).hasLength(2);
}
@Test
public void testMultipleChaining() throws IOException, SubtitleDecoderException {
TtmlSubtitle subtitle = getSubtitle(CHAIN_MULTIPLE_STYLES_TTML_FILE);
assertThat(subtitle.getEventTimeCount()).isEqualTo(2);
......@@ -265,6 +372,7 @@ public final class TtmlDecoderTest extends InstrumentationTestCase {
assertThat(style.isLinethrough()).isTrue();
}
@Test
public void testNoUnderline() throws IOException, SubtitleDecoderException {
TtmlSubtitle subtitle = getSubtitle(NO_UNDERLINE_LINETHROUGH_TTML_FILE);
assertThat(subtitle.getEventTimeCount()).isEqualTo(4);
......@@ -279,6 +387,7 @@ public final class TtmlDecoderTest extends InstrumentationTestCase {
.isFalse();
}
@Test
public void testNoLinethrough() throws IOException, SubtitleDecoderException {
TtmlSubtitle subtitle = getSubtitle(NO_UNDERLINE_LINETHROUGH_TTML_FILE);
assertThat(subtitle.getEventTimeCount()).isEqualTo(4);
......@@ -293,6 +402,7 @@ public final class TtmlDecoderTest extends InstrumentationTestCase {
.isFalse();
}
@Test
public void testFontSizeSpans() throws IOException, SubtitleDecoderException {
TtmlSubtitle subtitle = getSubtitle(FONT_SIZE_TTML_FILE);
assertThat(subtitle.getEventTimeCount()).isEqualTo(10);
......@@ -328,6 +438,7 @@ public final class TtmlDecoderTest extends InstrumentationTestCase {
assertRelativeFontSize(spannable, 0.5f);
}
@Test
public void testFontSizeWithMissingUnitIsIgnored() throws IOException, SubtitleDecoderException {
TtmlSubtitle subtitle = getSubtitle(FONT_SIZE_MISSING_UNIT_TTML_FILE);
assertThat(subtitle.getEventTimeCount()).isEqualTo(2);
......@@ -339,6 +450,7 @@ public final class TtmlDecoderTest extends InstrumentationTestCase {
assertThat(spannable.getSpans(0, spannable.length(), AbsoluteSizeSpan.class)).hasLength(0);
}
@Test
public void testFontSizeWithInvalidValueIsIgnored() throws IOException, SubtitleDecoderException {
TtmlSubtitle subtitle = getSubtitle(FONT_SIZE_INVALID_TTML_FILE);
assertThat(subtitle.getEventTimeCount()).isEqualTo(6);
......@@ -365,6 +477,7 @@ public final class TtmlDecoderTest extends InstrumentationTestCase {
assertThat(spannable.getSpans(0, spannable.length(), AbsoluteSizeSpan.class)).hasLength(0);
}
@Test
public void testFontSizeWithEmptyValueIsIgnored() throws IOException, SubtitleDecoderException {
TtmlSubtitle subtitle = getSubtitle(FONT_SIZE_EMPTY_TTML_FILE);
assertThat(subtitle.getEventTimeCount()).isEqualTo(2);
......@@ -376,6 +489,7 @@ public final class TtmlDecoderTest extends InstrumentationTestCase {
assertThat(spannable.getSpans(0, spannable.length(), AbsoluteSizeSpan.class)).hasLength(0);
}
@Test
public void testFrameRate() throws IOException, SubtitleDecoderException {
TtmlSubtitle subtitle = getSubtitle(FRAME_RATE_TTML_FILE);
assertThat(subtitle.getEventTimeCount()).isEqualTo(4);
......@@ -385,12 +499,19 @@ public final class TtmlDecoderTest extends InstrumentationTestCase {
assertThat((double) subtitle.getEventTime(3)).isWithin(2000).of(2_002_000_000);
}
private void assertSpans(TtmlSubtitle subtitle, int second,
String text, String font, int fontStyle,
int backgroundColor, int color, boolean isUnderline,
boolean isLinethrough, Layout.Alignment alignment) {
private void assertSpans(
TtmlSubtitle subtitle,
int second,
String text,
String font,
int fontStyle,
int backgroundColor,
int color,
boolean isUnderline,
boolean isLinethrough,
Layout.Alignment alignment) {
long timeUs = second * 1000000;
long timeUs = second * 1000000L;
List<Cue> cues = subtitle.getCues(timeUs);
assertThat(cues).hasSize(1);
......@@ -409,15 +530,15 @@ public final class TtmlDecoderTest extends InstrumentationTestCase {
}
private void assertAbsoluteFontSize(Spannable spannable, int absoluteFontSize) {
AbsoluteSizeSpan[] absoluteSizeSpans = spannable.getSpans(0, spannable.length(),
AbsoluteSizeSpan.class);
AbsoluteSizeSpan[] absoluteSizeSpans =
spannable.getSpans(0, spannable.length(), AbsoluteSizeSpan.class);
assertThat(absoluteSizeSpans).hasLength(1);
assertThat(absoluteSizeSpans[0].getSize()).isEqualTo(absoluteFontSize);
}
private void assertRelativeFontSize(Spannable spannable, float relativeFontSize) {
RelativeSizeSpan[] relativeSizeSpans = spannable.getSpans(0, spannable.length(),
RelativeSizeSpan.class);
RelativeSizeSpan[] relativeSizeSpans =
spannable.getSpans(0, spannable.length(), RelativeSizeSpan.class);
assertThat(relativeSizeSpans).hasLength(1);
assertThat(relativeSizeSpans[0].getSizeChange()).isEqualTo(relativeFontSize);
}
......@@ -440,8 +561,8 @@ public final class TtmlDecoderTest extends InstrumentationTestCase {
}
private void assertStrikethrough(Spannable spannable, boolean isStrikethrough) {
StrikethroughSpan[] striketroughSpans = spannable.getSpans(0, spannable.length(),
StrikethroughSpan.class);
StrikethroughSpan[] striketroughSpans =
spannable.getSpans(0, spannable.length(), StrikethroughSpan.class);
assertWithMessage(isStrikethrough ? "must be strikethrough" : "must not be strikethrough")
.that(striketroughSpans)
.hasLength(isStrikethrough ? 1 : 0);
......@@ -491,8 +612,7 @@ public final class TtmlDecoderTest extends InstrumentationTestCase {
private TtmlSubtitle getSubtitle(String file) throws IOException, SubtitleDecoderException {
TtmlDecoder ttmlDecoder = new TtmlDecoder();
byte[] bytes = TestUtil.getByteArray(getInstrumentation(), file);
byte[] bytes = TestUtil.getByteArray(RuntimeEnvironment.application, file);
return ttmlDecoder.decode(bytes, bytes.length, false);
}
}
......@@ -29,13 +29,11 @@ import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit test for {@link TtmlRenderUtil}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class TtmlRenderUtilTest {
@Test
......
......@@ -30,11 +30,9 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/** Unit test for {@link TtmlStyle}. */
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class TtmlStyleTest {
private static final String FONT_FAMILY = "serif";
......
......@@ -16,10 +16,10 @@
package com.google.android.exoplayer2.text.tx3g;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import android.graphics.Color;
import android.graphics.Typeface;
import android.test.InstrumentationTestCase;
import android.text.SpannedString;
import android.text.style.ForegroundColorSpan;
import android.text.style.StyleSpan;
......@@ -32,11 +32,14 @@ import com.google.android.exoplayer2.text.Subtitle;
import com.google.android.exoplayer2.text.SubtitleDecoderException;
import java.io.IOException;
import java.util.Collections;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
/**
* Unit test for {@link Tx3gDecoder}.
*/
public final class Tx3gDecoderTest extends InstrumentationTestCase {
/** Unit test for {@link Tx3gDecoder}. */
@RunWith(RobolectricTestRunner.class)
public final class Tx3gDecoderTest {
private static final String NO_SUBTITLE = "tx3g/no_subtitle";
private static final String SAMPLE_JUST_TEXT = "tx3g/sample_just_text";
......@@ -50,16 +53,18 @@ public final class Tx3gDecoderTest extends InstrumentationTestCase {
private static final String INITIALIZATION = "tx3g/initialization";
private static final String INITIALIZATION_ALL_DEFAULTS = "tx3g/initialization_all_defaults";
@Test
public void testDecodeNoSubtitle() throws IOException, SubtitleDecoderException {
Tx3gDecoder decoder = new Tx3gDecoder(Collections.<byte[]>emptyList());
byte[] bytes = TestUtil.getByteArray(getInstrumentation(), NO_SUBTITLE);
byte[] bytes = TestUtil.getByteArray(RuntimeEnvironment.application, NO_SUBTITLE);
Subtitle subtitle = decoder.decode(bytes, bytes.length, false);
assertThat(subtitle.getCues(0)).isEmpty();
}
@Test
public void testDecodeJustText() throws IOException, SubtitleDecoderException {
Tx3gDecoder decoder = new Tx3gDecoder(Collections.<byte[]>emptyList());
byte[] bytes = TestUtil.getByteArray(getInstrumentation(), SAMPLE_JUST_TEXT);
byte[] bytes = TestUtil.getByteArray(RuntimeEnvironment.application, SAMPLE_JUST_TEXT);
Subtitle subtitle = decoder.decode(bytes, bytes.length, false);
SpannedString text = new SpannedString(subtitle.getCues(0).get(0).text);
assertThat(text.toString()).isEqualTo("CC Test");
......@@ -67,9 +72,10 @@ public final class Tx3gDecoderTest extends InstrumentationTestCase {
assertFractionalLinePosition(subtitle.getCues(0).get(0), 0.85f);
}
@Test
public void testDecodeWithStyl() throws IOException, SubtitleDecoderException {
Tx3gDecoder decoder = new Tx3gDecoder(Collections.<byte[]>emptyList());
byte[] bytes = TestUtil.getByteArray(getInstrumentation(), SAMPLE_WITH_STYL);
byte[] bytes = TestUtil.getByteArray(RuntimeEnvironment.application, SAMPLE_WITH_STYL);
Subtitle subtitle = decoder.decode(bytes, bytes.length, false);
SpannedString text = new SpannedString(subtitle.getCues(0).get(0).text);
assertThat(text.toString()).isEqualTo("CC Test");
......@@ -82,9 +88,11 @@ public final class Tx3gDecoderTest extends InstrumentationTestCase {
assertFractionalLinePosition(subtitle.getCues(0).get(0), 0.85f);
}
@Test
public void testDecodeWithStylAllDefaults() throws IOException, SubtitleDecoderException {
Tx3gDecoder decoder = new Tx3gDecoder(Collections.<byte[]>emptyList());
byte[] bytes = TestUtil.getByteArray(getInstrumentation(), SAMPLE_WITH_STYL_ALL_DEFAULTS);
byte[] bytes =
TestUtil.getByteArray(RuntimeEnvironment.application, SAMPLE_WITH_STYL_ALL_DEFAULTS);
Subtitle subtitle = decoder.decode(bytes, bytes.length, false);
SpannedString text = new SpannedString(subtitle.getCues(0).get(0).text);
assertThat(text.toString()).isEqualTo("CC Test");
......@@ -92,9 +100,10 @@ public final class Tx3gDecoderTest extends InstrumentationTestCase {
assertFractionalLinePosition(subtitle.getCues(0).get(0), 0.85f);
}
@Test
public void testDecodeUtf16BeNoStyl() throws IOException, SubtitleDecoderException {
Tx3gDecoder decoder = new Tx3gDecoder(Collections.<byte[]>emptyList());
byte[] bytes = TestUtil.getByteArray(getInstrumentation(), SAMPLE_UTF16_BE_NO_STYL);
byte[] bytes = TestUtil.getByteArray(RuntimeEnvironment.application, SAMPLE_UTF16_BE_NO_STYL);
Subtitle subtitle = decoder.decode(bytes, bytes.length, false);
SpannedString text = new SpannedString(subtitle.getCues(0).get(0).text);
assertThat(text.toString()).isEqualTo("你好");
......@@ -102,9 +111,10 @@ public final class Tx3gDecoderTest extends InstrumentationTestCase {
assertFractionalLinePosition(subtitle.getCues(0).get(0), 0.85f);
}
@Test
public void testDecodeUtf16LeNoStyl() throws IOException, SubtitleDecoderException {
Tx3gDecoder decoder = new Tx3gDecoder(Collections.<byte[]>emptyList());
byte[] bytes = TestUtil.getByteArray(getInstrumentation(), SAMPLE_UTF16_LE_NO_STYL);
byte[] bytes = TestUtil.getByteArray(RuntimeEnvironment.application, SAMPLE_UTF16_LE_NO_STYL);
Subtitle subtitle = decoder.decode(bytes, bytes.length, false);
SpannedString text = new SpannedString(subtitle.getCues(0).get(0).text);
assertThat(text.toString()).isEqualTo("你好");
......@@ -112,9 +122,10 @@ public final class Tx3gDecoderTest extends InstrumentationTestCase {
assertFractionalLinePosition(subtitle.getCues(0).get(0), 0.85f);
}
@Test
public void testDecodeWithMultipleStyl() throws IOException, SubtitleDecoderException {
Tx3gDecoder decoder = new Tx3gDecoder(Collections.<byte[]>emptyList());
byte[] bytes = TestUtil.getByteArray(getInstrumentation(), SAMPLE_WITH_MULTIPLE_STYL);
byte[] bytes = TestUtil.getByteArray(RuntimeEnvironment.application, SAMPLE_WITH_MULTIPLE_STYL);
Subtitle subtitle = decoder.decode(bytes, bytes.length, false);
SpannedString text = new SpannedString(subtitle.getCues(0).get(0).text);
assertThat(text.toString()).isEqualTo("Line 2\nLine 3");
......@@ -129,9 +140,11 @@ public final class Tx3gDecoderTest extends InstrumentationTestCase {
assertFractionalLinePosition(subtitle.getCues(0).get(0), 0.85f);
}
@Test
public void testDecodeWithOtherExtension() throws IOException, SubtitleDecoderException {
Tx3gDecoder decoder = new Tx3gDecoder(Collections.<byte[]>emptyList());
byte[] bytes = TestUtil.getByteArray(getInstrumentation(), SAMPLE_WITH_OTHER_EXTENSION);
byte[] bytes =
TestUtil.getByteArray(RuntimeEnvironment.application, SAMPLE_WITH_OTHER_EXTENSION);
Subtitle subtitle = decoder.decode(bytes, bytes.length, false);
SpannedString text = new SpannedString(subtitle.getCues(0).get(0).text);
assertThat(text.toString()).isEqualTo("CC Test");
......@@ -143,10 +156,11 @@ public final class Tx3gDecoderTest extends InstrumentationTestCase {
assertFractionalLinePosition(subtitle.getCues(0).get(0), 0.85f);
}
@Test
public void testInitializationDecodeWithStyl() throws IOException, SubtitleDecoderException {
byte[] initBytes = TestUtil.getByteArray(getInstrumentation(), INITIALIZATION);
byte[] initBytes = TestUtil.getByteArray(RuntimeEnvironment.application, INITIALIZATION);
Tx3gDecoder decoder = new Tx3gDecoder(Collections.singletonList(initBytes));
byte[] bytes = TestUtil.getByteArray(getInstrumentation(), SAMPLE_WITH_STYL);
byte[] bytes = TestUtil.getByteArray(RuntimeEnvironment.application, SAMPLE_WITH_STYL);
Subtitle subtitle = decoder.decode(bytes, bytes.length, false);
SpannedString text = new SpannedString(subtitle.getCues(0).get(0).text);
assertThat(text.toString()).isEqualTo("CC Test");
......@@ -163,10 +177,11 @@ public final class Tx3gDecoderTest extends InstrumentationTestCase {
assertFractionalLinePosition(subtitle.getCues(0).get(0), 0.1f);
}
@Test
public void testInitializationDecodeWithTbox() throws IOException, SubtitleDecoderException {
byte[] initBytes = TestUtil.getByteArray(getInstrumentation(), INITIALIZATION);
byte[] initBytes = TestUtil.getByteArray(RuntimeEnvironment.application, INITIALIZATION);
Tx3gDecoder decoder = new Tx3gDecoder(Collections.singletonList(initBytes));
byte[] bytes = TestUtil.getByteArray(getInstrumentation(), SAMPLE_WITH_TBOX);
byte[] bytes = TestUtil.getByteArray(RuntimeEnvironment.application, SAMPLE_WITH_TBOX);
Subtitle subtitle = decoder.decode(bytes, bytes.length, false);
SpannedString text = new SpannedString(subtitle.getCues(0).get(0).text);
assertThat(text.toString()).isEqualTo("CC Test");
......@@ -181,11 +196,13 @@ public final class Tx3gDecoderTest extends InstrumentationTestCase {
assertFractionalLinePosition(subtitle.getCues(0).get(0), 0.1875f);
}
public void testInitializationAllDefaultsDecodeWithStyl() throws IOException,
SubtitleDecoderException {
byte[] initBytes = TestUtil.getByteArray(getInstrumentation(), INITIALIZATION_ALL_DEFAULTS);
@Test
public void testInitializationAllDefaultsDecodeWithStyl()
throws IOException, SubtitleDecoderException {
byte[] initBytes =
TestUtil.getByteArray(RuntimeEnvironment.application, INITIALIZATION_ALL_DEFAULTS);
Tx3gDecoder decoder = new Tx3gDecoder(Collections.singletonList(initBytes));
byte[] bytes = TestUtil.getByteArray(getInstrumentation(), SAMPLE_WITH_STYL);
byte[] bytes = TestUtil.getByteArray(RuntimeEnvironment.application, SAMPLE_WITH_STYL);
Subtitle subtitle = decoder.decode(bytes, bytes.length, false);
SpannedString text = new SpannedString(subtitle.getCues(0).get(0).text);
assertThat(text.toString()).isEqualTo("CC Test");
......@@ -198,8 +215,8 @@ public final class Tx3gDecoderTest extends InstrumentationTestCase {
assertFractionalLinePosition(subtitle.getCues(0).get(0), 0.85f);
}
private static <T> T findSpan(SpannedString testObject, int expectedStart, int expectedEnd,
Class<T> expectedType) {
private static <T> T findSpan(
SpannedString testObject, int expectedStart, int expectedEnd, Class<T> expectedType) {
T[] spans = testObject.getSpans(0, testObject.length(), expectedType);
for (T span : spans) {
if (testObject.getSpanStart(span) == expectedStart
......@@ -216,5 +233,4 @@ public final class Tx3gDecoderTest extends InstrumentationTestCase {
assertThat(cue.lineAnchor).isEqualTo(Cue.ANCHOR_TYPE_START);
assertThat(Math.abs(expectedFraction - cue.line) < 1e-6).isTrue();
}
}
......@@ -24,13 +24,11 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit test for {@link CssParser}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class CssParserTest {
private CssParser parser;
......
......@@ -25,13 +25,11 @@ import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit test for {@link Mp4WebvttDecoder}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class Mp4WebvttDecoderTest {
private static final byte[] SINGLE_CUE_SAMPLE = {
......
......@@ -27,13 +27,11 @@ import java.util.Collections;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit test for {@link WebvttCueParser}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class WebvttCueParserTest {
@Test
......
......@@ -16,9 +16,9 @@
package com.google.android.exoplayer2.text.webvtt;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import android.graphics.Typeface;
import android.test.InstrumentationTestCase;
import android.text.Layout.Alignment;
import android.text.Spanned;
import android.text.style.BackgroundColorSpan;
......@@ -31,11 +31,14 @@ import com.google.android.exoplayer2.text.Cue;
import com.google.android.exoplayer2.text.SubtitleDecoderException;
import java.io.IOException;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
/**
* Unit test for {@link WebvttDecoder}.
*/
public class WebvttDecoderTest extends InstrumentationTestCase {
/** Unit test for {@link WebvttDecoder}. */
@RunWith(RobolectricTestRunner.class)
public class WebvttDecoderTest {
private static final String TYPICAL_FILE = "webvtt/typical";
private static final String TYPICAL_WITH_BAD_TIMESTAMPS = "webvtt/typical_with_bad_timestamps";
......@@ -48,9 +51,10 @@ public class WebvttDecoderTest extends InstrumentationTestCase {
private static final String WITH_CSS_COMPLEX_SELECTORS = "webvtt/with_css_complex_selectors";
private static final String EMPTY_FILE = "webvtt/empty";
@Test
public void testDecodeEmpty() throws IOException {
WebvttDecoder decoder = new WebvttDecoder();
byte[] bytes = TestUtil.getByteArray(getInstrumentation(), EMPTY_FILE);
byte[] bytes = TestUtil.getByteArray(RuntimeEnvironment.application, EMPTY_FILE);
try {
decoder.decode(bytes, bytes.length, false);
fail();
......@@ -59,6 +63,7 @@ public class WebvttDecoderTest extends InstrumentationTestCase {
}
}
@Test
public void testDecodeTypical() throws IOException, SubtitleDecoderException {
WebvttSubtitle subtitle = getSubtitleForTestAsset(TYPICAL_FILE);
......@@ -70,6 +75,7 @@ public class WebvttDecoderTest extends InstrumentationTestCase {
assertCue(subtitle, 2, 2345000, 3456000, "This is the second subtitle.");
}
@Test
public void testDecodeTypicalWithBadTimestamps() throws IOException, SubtitleDecoderException {
WebvttSubtitle subtitle = getSubtitleForTestAsset(TYPICAL_WITH_BAD_TIMESTAMPS);
......@@ -81,6 +87,7 @@ public class WebvttDecoderTest extends InstrumentationTestCase {
assertCue(subtitle, 2, 2345000, 3456000, "This is the second subtitle.");
}
@Test
public void testDecodeTypicalWithIds() throws IOException, SubtitleDecoderException {
WebvttSubtitle subtitle = getSubtitleForTestAsset(TYPICAL_WITH_IDS_FILE);
......@@ -92,6 +99,7 @@ public class WebvttDecoderTest extends InstrumentationTestCase {
assertCue(subtitle, 2, 2345000, 3456000, "This is the second subtitle.");
}
@Test
public void testDecodeTypicalWithComments() throws IOException, SubtitleDecoderException {
WebvttSubtitle subtitle = getSubtitleForTestAsset(TYPICAL_WITH_COMMENTS_FILE);
......@@ -103,6 +111,7 @@ public class WebvttDecoderTest extends InstrumentationTestCase {
assertCue(subtitle, 2, 2345000, 3456000, "This is the second subtitle.");
}
@Test
public void testDecodeWithTags() throws IOException, SubtitleDecoderException {
WebvttSubtitle subtitle = getSubtitleForTestAsset(WITH_TAGS_FILE);
......@@ -116,30 +125,93 @@ public class WebvttDecoderTest extends InstrumentationTestCase {
assertCue(subtitle, 6, 6000000, 7000000, "This is the <fourth> &subtitle.");
}
@Test
public void testDecodeWithPositioning() throws IOException, SubtitleDecoderException {
WebvttSubtitle subtitle = getSubtitleForTestAsset(WITH_POSITIONING_FILE);
// Test event count.
assertThat(subtitle.getEventTimeCount()).isEqualTo(12);
// Test cues.
assertCue(subtitle, 0, 0, 1234000, "This is the first subtitle.", Alignment.ALIGN_NORMAL,
Cue.DIMEN_UNSET, Cue.TYPE_UNSET, Cue.TYPE_UNSET, 0.1f, Cue.ANCHOR_TYPE_START, 0.35f);
assertCue(subtitle, 2, 2345000, 3456000, "This is the second subtitle.",
Alignment.ALIGN_OPPOSITE, Cue.DIMEN_UNSET, Cue.TYPE_UNSET, Cue.TYPE_UNSET, Cue.DIMEN_UNSET,
Cue.TYPE_UNSET, 0.35f);
assertCue(subtitle, 4, 4000000, 5000000, "This is the third subtitle.",
Alignment.ALIGN_CENTER, 0.45f, Cue.LINE_TYPE_FRACTION, Cue.ANCHOR_TYPE_END, Cue.DIMEN_UNSET,
Cue.TYPE_UNSET, 0.35f);
assertCue(subtitle, 6, 6000000, 7000000, "This is the fourth subtitle.",
Alignment.ALIGN_CENTER, -11f, Cue.LINE_TYPE_NUMBER, Cue.TYPE_UNSET, Cue.DIMEN_UNSET,
Cue.TYPE_UNSET, Cue.DIMEN_UNSET);
assertCue(subtitle, 8, 7000000, 8000000, "This is the fifth subtitle.",
Alignment.ALIGN_OPPOSITE, Cue.DIMEN_UNSET, Cue.TYPE_UNSET, Cue.TYPE_UNSET, 0.1f,
Cue.ANCHOR_TYPE_END, 0.1f);
assertCue(subtitle, 10, 10000000, 11000000, "This is the sixth subtitle.",
Alignment.ALIGN_CENTER, 0.45f, Cue.LINE_TYPE_FRACTION, Cue.ANCHOR_TYPE_END, Cue.DIMEN_UNSET,
Cue.TYPE_UNSET, 0.35f);
assertCue(
subtitle,
0,
0,
1234000,
"This is the first subtitle.",
Alignment.ALIGN_NORMAL,
Cue.DIMEN_UNSET,
Cue.TYPE_UNSET,
Cue.TYPE_UNSET,
0.1f,
Cue.ANCHOR_TYPE_START,
0.35f);
assertCue(
subtitle,
2,
2345000,
3456000,
"This is the second subtitle.",
Alignment.ALIGN_OPPOSITE,
Cue.DIMEN_UNSET,
Cue.TYPE_UNSET,
Cue.TYPE_UNSET,
Cue.DIMEN_UNSET,
Cue.TYPE_UNSET,
0.35f);
assertCue(
subtitle,
4,
4000000,
5000000,
"This is the third subtitle.",
Alignment.ALIGN_CENTER,
0.45f,
Cue.LINE_TYPE_FRACTION,
Cue.ANCHOR_TYPE_END,
Cue.DIMEN_UNSET,
Cue.TYPE_UNSET,
0.35f);
assertCue(
subtitle,
6,
6000000,
7000000,
"This is the fourth subtitle.",
Alignment.ALIGN_CENTER,
-11f,
Cue.LINE_TYPE_NUMBER,
Cue.TYPE_UNSET,
Cue.DIMEN_UNSET,
Cue.TYPE_UNSET,
Cue.DIMEN_UNSET);
assertCue(
subtitle,
8,
7000000,
8000000,
"This is the fifth subtitle.",
Alignment.ALIGN_OPPOSITE,
Cue.DIMEN_UNSET,
Cue.TYPE_UNSET,
Cue.TYPE_UNSET,
0.1f,
Cue.ANCHOR_TYPE_END,
0.1f);
assertCue(
subtitle,
10,
10000000,
11000000,
"This is the sixth subtitle.",
Alignment.ALIGN_CENTER,
0.45f,
Cue.LINE_TYPE_FRACTION,
Cue.ANCHOR_TYPE_END,
Cue.DIMEN_UNSET,
Cue.TYPE_UNSET,
0.35f);
}
@Test
public void testDecodeWithBadCueHeader() throws IOException, SubtitleDecoderException {
WebvttSubtitle subtitle = getSubtitleForTestAsset(WITH_BAD_CUE_HEADER_FILE);
......@@ -151,6 +223,7 @@ public class WebvttDecoderTest extends InstrumentationTestCase {
assertCue(subtitle, 2, 4000000, 5000000, "This is the third subtitle.");
}
@Test
public void testWebvttWithCssStyle() throws IOException, SubtitleDecoderException {
WebvttSubtitle subtitle = getSubtitleForTestAsset(WITH_CSS_STYLES);
......@@ -175,6 +248,7 @@ public class WebvttDecoderTest extends InstrumentationTestCase {
.isEqualTo(Typeface.BOLD);
}
@Test
public void testWithComplexCssSelectors() throws IOException, SubtitleDecoderException {
WebvttSubtitle subtitle = getSubtitleForTestAsset(WITH_CSS_COMPLEX_SELECTORS);
Spanned text = getUniqueSpanTextAt(subtitle, 0);
......@@ -211,10 +285,10 @@ public class WebvttDecoderTest extends InstrumentationTestCase {
.isEqualTo(Typeface.ITALIC);
}
private WebvttSubtitle getSubtitleForTestAsset(String asset) throws IOException,
SubtitleDecoderException {
private WebvttSubtitle getSubtitleForTestAsset(String asset)
throws IOException, SubtitleDecoderException {
WebvttDecoder decoder = new WebvttDecoder();
byte[] bytes = TestUtil.getByteArray(getInstrumentation(), asset);
byte[] bytes = TestUtil.getByteArray(RuntimeEnvironment.application, asset);
return decoder.decode(bytes, bytes.length, false);
}
......@@ -222,15 +296,36 @@ public class WebvttDecoderTest extends InstrumentationTestCase {
return (Spanned) sub.getCues(timeUs).get(0).text;
}
private static void assertCue(WebvttSubtitle subtitle, int eventTimeIndex, long startTimeUs,
int endTimeUs, String text) {
assertCue(subtitle, eventTimeIndex, startTimeUs, endTimeUs, text, null, Cue.DIMEN_UNSET,
Cue.TYPE_UNSET, Cue.TYPE_UNSET, Cue.DIMEN_UNSET, Cue.TYPE_UNSET, Cue.DIMEN_UNSET);
private static void assertCue(
WebvttSubtitle subtitle, int eventTimeIndex, long startTimeUs, int endTimeUs, String text) {
assertCue(
subtitle,
eventTimeIndex,
startTimeUs,
endTimeUs,
text,
null,
Cue.DIMEN_UNSET,
Cue.TYPE_UNSET,
Cue.TYPE_UNSET,
Cue.DIMEN_UNSET,
Cue.TYPE_UNSET,
Cue.DIMEN_UNSET);
}
private static void assertCue(WebvttSubtitle subtitle, int eventTimeIndex, long startTimeUs,
int endTimeUs, String text, Alignment textAlignment, float line, int lineType, int lineAnchor,
float position, int positionAnchor, float size) {
private static void assertCue(
WebvttSubtitle subtitle,
int eventTimeIndex,
long startTimeUs,
int endTimeUs,
String text,
Alignment textAlignment,
float line,
int lineType,
int lineAnchor,
float position,
int positionAnchor,
float size) {
assertThat(subtitle.getEventTime(eventTimeIndex)).isEqualTo(startTimeUs);
assertThat(subtitle.getEventTime(eventTimeIndex + 1)).isEqualTo(endTimeUs);
List<Cue> cues = subtitle.getCues(subtitle.getEventTime(eventTimeIndex));
......@@ -246,5 +341,4 @@ public class WebvttDecoderTest extends InstrumentationTestCase {
assertThat(cue.positionAnchor).isEqualTo(positionAnchor);
assertThat(cue.size).isEqualTo(size);
}
}
......@@ -26,13 +26,11 @@ import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit test for {@link WebvttSubtitle}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public class WebvttSubtitleTest {
private static final String FIRST_SUBTITLE_STRING = "This is the first subtitle.";
......
......@@ -38,11 +38,9 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/** Unit test for {@link AdaptiveTrackSelection}. */
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class AdaptiveTrackSelectionTest {
@Mock private BandwidthMeter mockBandwidthMeter;
......
......@@ -25,13 +25,11 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit tests for {@link DefaultTrackSelector}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class DefaultTrackSelectorTest {
private static final RendererCapabilities ALL_AUDIO_FORMAT_SUPPORTED_RENDERER_CAPABILITIES =
......
......@@ -30,13 +30,11 @@ import java.util.Arrays;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit tests for {@link MappingTrackSelector}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class MappingTrackSelectorTest {
private static final RendererCapabilities VIDEO_CAPABILITIES =
......
......@@ -16,28 +16,37 @@
package com.google.android.exoplayer2.upstream;
import android.net.Uri;
import android.test.InstrumentationTestCase;
import com.google.android.exoplayer2.testutil.TestUtil;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
/**
* Unit tests for {@link AssetDataSource}.
*/
public final class AssetDataSourceTest extends InstrumentationTestCase {
/** Unit tests for {@link AssetDataSource}. */
@RunWith(RobolectricTestRunner.class)
public final class AssetDataSourceTest {
private static final String DATA_PATH = "binary/1024_incrementing_bytes.mp3";
@Test
public void testReadFileUri() throws Exception {
AssetDataSource dataSource = new AssetDataSource(getInstrumentation().getContext());
AssetDataSource dataSource = new AssetDataSource(RuntimeEnvironment.application);
DataSpec dataSpec = new DataSpec(Uri.parse("file:///android_asset/" + DATA_PATH));
TestUtil.assertDataSourceContent(dataSource, dataSpec,
TestUtil.getByteArray(getInstrumentation(), DATA_PATH), true);
TestUtil.assertDataSourceContent(
dataSource,
dataSpec,
TestUtil.getByteArray(RuntimeEnvironment.application, DATA_PATH),
true);
}
@Test
public void testReadAssetUri() throws Exception {
AssetDataSource dataSource = new AssetDataSource(getInstrumentation().getContext());
AssetDataSource dataSource = new AssetDataSource(RuntimeEnvironment.application);
DataSpec dataSpec = new DataSpec(Uri.parse("asset:///" + DATA_PATH));
TestUtil.assertDataSourceContent(dataSource, dataSpec,
TestUtil.getByteArray(getInstrumentation(), DATA_PATH), true);
TestUtil.assertDataSourceContent(
dataSource,
dataSpec,
TestUtil.getByteArray(RuntimeEnvironment.application, DATA_PATH),
true);
}
}
......@@ -23,13 +23,11 @@ import java.io.IOException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit tests for {@link ByteArrayDataSource}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class ByteArrayDataSourceTest {
private static final byte[] TEST_DATA = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
......
......@@ -27,13 +27,11 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit tests for {@link DataSchemeDataSource}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class DataSchemeDataSourceTest {
private DataSource schemeDataDataSource;
......
......@@ -25,13 +25,11 @@ import java.util.Arrays;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit tests for {@link DataSourceInputStream}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class DataSourceInputStreamTest {
private static final byte[] TEST_DATA = TestUtil.buildTestData(16);
......
......@@ -37,13 +37,11 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
/**
* Unit tests for {@link CacheDataSource}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class CacheDataSourceTest {
private static final byte[] TEST_DATA = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
......
......@@ -39,13 +39,11 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
/**
* Additional tests for {@link CacheDataSource}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class CacheDataSourceTest2 {
private static final String EXO_CACHE_DIR = "exo";
......
......@@ -44,13 +44,11 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
/**
* Tests {@link CacheUtil}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class CacheUtilTest {
/**
......
......@@ -20,29 +20,37 @@ import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.when;
import android.test.InstrumentationTestCase;
import com.google.android.exoplayer2.extractor.ChunkIndex;
import com.google.android.exoplayer2.testutil.MockitoUtil;
import com.google.android.exoplayer2.util.Util;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.TreeSet;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
/**
* Tests for {@link CachedRegionTracker}.
*/
public final class CachedRegionTrackerTest extends InstrumentationTestCase {
/** Tests for {@link CachedRegionTracker}. */
@RunWith(RobolectricTestRunner.class)
public final class CachedRegionTrackerTest {
private static final String CACHE_KEY = "abc";
private static final long MS_IN_US = 1000;
// 5 chunks, each 20 bytes long and 100 ms long.
private static final ChunkIndex CHUNK_INDEX = new ChunkIndex(
new int[] {20, 20, 20, 20, 20},
new long[] {100, 120, 140, 160, 180},
new long[] {100 * MS_IN_US, 100 * MS_IN_US, 100 * MS_IN_US, 100 * MS_IN_US, 100 * MS_IN_US},
new long[] {0, 100 * MS_IN_US, 200 * MS_IN_US, 300 * MS_IN_US, 400 * MS_IN_US});
private static final ChunkIndex CHUNK_INDEX =
new ChunkIndex(
new int[] {20, 20, 20, 20, 20},
new long[] {100, 120, 140, 160, 180},
new long[] {
100 * MS_IN_US, 100 * MS_IN_US, 100 * MS_IN_US, 100 * MS_IN_US, 100 * MS_IN_US
},
new long[] {0, 100 * MS_IN_US, 200 * MS_IN_US, 300 * MS_IN_US, 400 * MS_IN_US});
@Mock private Cache cache;
private CachedRegionTracker tracker;
......@@ -50,68 +58,59 @@ public final class CachedRegionTrackerTest extends InstrumentationTestCase {
private CachedContentIndex index;
private File cacheDir;
@Override
protected void setUp() throws Exception {
super.setUp();
MockitoUtil.setUpMockito(this);
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
when(cache.addListener(anyString(), any(Cache.Listener.class)))
.thenReturn(new TreeSet<CacheSpan>());
tracker = new CachedRegionTracker(cache, CACHE_KEY, CHUNK_INDEX);
cacheDir = Util.createTempDirectory(getInstrumentation().getContext(), "ExoPlayerTest");
cacheDir = Util.createTempDirectory(RuntimeEnvironment.application, "ExoPlayerTest");
index = new CachedContentIndex(cacheDir);
}
@Override
protected void tearDown() throws Exception {
@After
public void tearDown() throws Exception {
Util.recursiveDelete(cacheDir);
super.tearDown();
}
@Test
public void testGetRegion_noSpansInCache() {
assertThat(tracker.getRegionEndTimeMs(100)).isEqualTo(CachedRegionTracker.NOT_CACHED);
assertThat(tracker.getRegionEndTimeMs(150)).isEqualTo(CachedRegionTracker.NOT_CACHED);
}
@Test
public void testGetRegion_fullyCached() throws Exception {
tracker.onSpanAdded(
cache,
newCacheSpan(100, 100));
tracker.onSpanAdded(cache, newCacheSpan(100, 100));
assertThat(tracker.getRegionEndTimeMs(101)).isEqualTo(CachedRegionTracker.CACHED_TO_END);
assertThat(tracker.getRegionEndTimeMs(121)).isEqualTo(CachedRegionTracker.CACHED_TO_END);
}
@Test
public void testGetRegion_partiallyCached() throws Exception {
tracker.onSpanAdded(
cache,
newCacheSpan(100, 40));
tracker.onSpanAdded(cache, newCacheSpan(100, 40));
assertThat(tracker.getRegionEndTimeMs(101)).isEqualTo(200);
assertThat(tracker.getRegionEndTimeMs(121)).isEqualTo(200);
}
@Test
public void testGetRegion_multipleSpanAddsJoinedCorrectly() throws Exception {
tracker.onSpanAdded(
cache,
newCacheSpan(100, 20));
tracker.onSpanAdded(
cache,
newCacheSpan(120, 20));
tracker.onSpanAdded(cache, newCacheSpan(100, 20));
tracker.onSpanAdded(cache, newCacheSpan(120, 20));
assertThat(tracker.getRegionEndTimeMs(101)).isEqualTo(200);
assertThat(tracker.getRegionEndTimeMs(121)).isEqualTo(200);
}
@Test
public void testGetRegion_fullyCachedThenPartiallyRemoved() throws Exception {
// Start with the full stream in cache.
tracker.onSpanAdded(
cache,
newCacheSpan(100, 100));
tracker.onSpanAdded(cache, newCacheSpan(100, 100));
// Remove the middle bit.
tracker.onSpanRemoved(
cache,
newCacheSpan(140, 40));
tracker.onSpanRemoved(cache, newCacheSpan(140, 40));
assertThat(tracker.getRegionEndTimeMs(101)).isEqualTo(200);
assertThat(tracker.getRegionEndTimeMs(121)).isEqualTo(200);
......@@ -119,17 +118,32 @@ public final class CachedRegionTrackerTest extends InstrumentationTestCase {
assertThat(tracker.getRegionEndTimeMs(181)).isEqualTo(CachedRegionTracker.CACHED_TO_END);
}
@Test
public void testGetRegion_subchunkEstimation() throws Exception {
tracker.onSpanAdded(
cache,
newCacheSpan(100, 10));
tracker.onSpanAdded(cache, newCacheSpan(100, 10));
assertThat(tracker.getRegionEndTimeMs(101)).isEqualTo(50);
assertThat(tracker.getRegionEndTimeMs(111)).isEqualTo(CachedRegionTracker.NOT_CACHED);
}
private CacheSpan newCacheSpan(int position, int length) throws IOException {
return SimpleCacheSpanTest.createCacheSpan(index, cacheDir, CACHE_KEY, position, length, 0);
int id = index.assignIdForKey(CACHE_KEY);
File cacheFile = createCacheSpanFile(cacheDir, id, position, length, 0);
return SimpleCacheSpan.createCacheEntry(cacheFile, index);
}
public static File createCacheSpanFile(
File cacheDir, int id, long offset, int length, long lastAccessTimestamp) throws IOException {
File cacheFile = SimpleCacheSpan.getCacheFile(cacheDir, id, offset, lastAccessTimestamp);
createTestFile(cacheFile, length);
return cacheFile;
}
private static void createTestFile(File file, int length) throws IOException {
FileOutputStream output = new FileOutputStream(file);
for (int i = 0; i < length; i++) {
output.write(i);
}
output.close();
}
}
......@@ -21,13 +21,11 @@ import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit tests for {@link LeastRecentlyUsedCacheEvictor}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public class LeastRecentlyUsedCacheEvictorTest {
@Before
......
......@@ -41,13 +41,11 @@ import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
/**
* Unit tests for {@link SimpleCache}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public class SimpleCacheTest {
private static final String KEY_1 = "key1";
......
......@@ -26,13 +26,11 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit tests for {@link AesFlushingCipher}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public class AesFlushingCipherTest {
private static final int DATA_LENGTH = 65536;
......
......@@ -27,13 +27,11 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
/**
* Tests {@link AtomicFile}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class AtomicFileTest {
private File tempFolder;
......
......@@ -27,13 +27,11 @@ import android.graphics.Color;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit test for <code>ColorParser</code>.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class ColorParserTest {
// Negative tests.
......
......@@ -23,13 +23,11 @@ import java.util.Arrays;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Tests for {@link NalUnitUtil}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class NalUnitUtilTest {
private static final int TEST_PARTIAL_NAL_POSITION = 4;
......
......@@ -21,13 +21,11 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Tests for {@link ParsableBitArray}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class ParsableBitArrayTest {
private static final byte[] TEST_DATA = new byte[] {0x3C, (byte) 0xD2, (byte) 0x5F, (byte) 0x01,
......
......@@ -24,13 +24,11 @@ import java.util.Arrays;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Tests for {@link ParsableByteArray}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class ParsableByteArrayTest {
private static final byte[] TEST_DATA =
......
......@@ -22,13 +22,11 @@ import static org.junit.Assert.fail;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Tests for {@link ParsableNalUnitBitArray}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class ParsableNalUnitBitArrayTest {
private static final byte[] NO_ESCAPING_TEST_DATA = createByteArray(0, 3, 0, 1, 3, 0, 0);
......
......@@ -21,13 +21,11 @@ import java.io.ByteArrayOutputStream;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Tests {@link ReusableBufferedOutputStream}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class ReusableBufferedOutputStreamTest {
private static final byte[] TEST_DATA_1 = "test data 1".getBytes();
......
......@@ -21,13 +21,11 @@ import static com.google.common.truth.Truth.assertThat;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit tests for {@link UriUtil}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class UriUtilTest {
/**
......
......@@ -32,13 +32,11 @@ import java.util.Random;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit tests for {@link Util}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public class UtilTest {
@Test
......
......@@ -17,7 +17,7 @@ package com.google.android.exoplayer2.testutil;
import static com.google.common.truth.Truth.assertThat;
import android.app.Instrumentation;
import android.content.Context;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.extractor.Extractor;
import com.google.android.exoplayer2.extractor.ExtractorInput;
......@@ -27,6 +27,7 @@ import com.google.android.exoplayer2.extractor.SeekMap;
import com.google.android.exoplayer2.testutil.FakeExtractorInput.SimulatedIOException;
import com.google.android.exoplayer2.util.Assertions;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Arrays;
/**
......@@ -34,6 +35,22 @@ import java.util.Arrays;
*/
public final class ExtractorAsserts {
private static Context robolectricContext;
static {
try {
Class<?> runtimeEnvironmentClass = Class.forName("org.robolectric.RuntimeEnvironment");
Field applicationField = runtimeEnvironmentClass.getDeclaredField("application");
robolectricContext = (Context) applicationField.get(null);
} catch (ClassNotFoundException e) {
// Keep Robolectric context at null if not found.
} catch (NoSuchFieldException e) {
// Keep Robolectric context at null if not found.
} catch (IllegalAccessException e) {
// Keep Robolectric context at null if not found.
}
}
/**
* A factory for {@link Extractor} instances.
*/
......@@ -45,57 +62,87 @@ public final class ExtractorAsserts {
private static final String UNKNOWN_LENGTH_EXTENSION = ".unklen" + DUMP_EXTENSION;
/**
* Asserts that an extractor behaves correctly given valid input data. Can only be used from
* Robolectric tests.
*
* <ul>
* <li>Calls {@link Extractor#seek(long, long)} and {@link Extractor#release()} without calling
* {@link Extractor#init(ExtractorOutput)} to check these calls do not fail.
* <li>Calls {@link #assertOutput(Extractor, String, byte[], Context, boolean, boolean, boolean,
* boolean)} with all possible combinations of "simulate" parameters.
* </ul>
*
* @param factory An {@link ExtractorFactory} which creates instances of the {@link Extractor}
* class which is to be tested.
* @param file The path to the input sample.
* @throws IOException If reading from the input fails.
* @throws InterruptedException If interrupted while reading from the input.
*/
public static void assertBehavior(ExtractorFactory factory, String file)
throws IOException, InterruptedException {
// Check behavior prior to initialization.
Extractor extractor = factory.create();
extractor.seek(0, 0);
extractor.release();
// Assert output.
byte[] fileData = TestUtil.getByteArray(robolectricContext, file);
assertOutput(factory, file, fileData, robolectricContext);
}
/**
* Asserts that an extractor behaves correctly given valid input data:
*
* <ul>
* <li>Calls {@link Extractor#seek(long, long)} and {@link Extractor#release()} without calling
* {@link Extractor#init(ExtractorOutput)} to check these calls do not fail.</li>
* <li>Calls {@link #assertOutput(Extractor, String, byte[], Instrumentation, boolean, boolean,
* boolean, boolean)} with all possible combinations of "simulate" parameters.</li>
* {@link Extractor#init(ExtractorOutput)} to check these calls do not fail.
* <li>Calls {@link #assertOutput(Extractor, String, byte[], Context, boolean, boolean, boolean,
* boolean)} with all possible combinations of "simulate" parameters.
* </ul>
*
* @param factory An {@link ExtractorFactory} which creates instances of the {@link Extractor}
* class which is to be tested.
* @param file The path to the input sample.
* @param instrumentation To be used to load the sample file.
* @param context To be used to load the sample file.
* @throws IOException If reading from the input fails.
* @throws InterruptedException If interrupted while reading from the input.
*/
public static void assertBehavior(ExtractorFactory factory, String file,
Instrumentation instrumentation) throws IOException, InterruptedException {
public static void assertBehavior(ExtractorFactory factory, String file, Context context)
throws IOException, InterruptedException {
// Check behavior prior to initialization.
Extractor extractor = factory.create();
extractor.seek(0, 0);
extractor.release();
// Assert output.
byte[] fileData = TestUtil.getByteArray(instrumentation, file);
assertOutput(factory, file, fileData, instrumentation);
byte[] fileData = TestUtil.getByteArray(context, file);
assertOutput(factory, file, fileData, context);
}
/**
* Calls {@link #assertOutput(Extractor, String, byte[], Instrumentation, boolean, boolean,
* boolean, boolean)} with all possible combinations of "simulate" parameters with
* {@code sniffFirst} set to true, and makes one additional call with the "simulate" and
* {@code sniffFirst} parameters all set to false.
* Calls {@link #assertOutput(Extractor, String, byte[], Context, boolean, boolean, boolean,
* boolean)} with all possible combinations of "simulate" parameters with {@code sniffFirst} set
* to true, and makes one additional call with the "simulate" and {@code sniffFirst} parameters
* all set to false.
*
* @param factory An {@link ExtractorFactory} which creates instances of the {@link Extractor}
* class which is to be tested.
* @param file The path to the input sample.
* @param data Content of the input file.
* @param instrumentation To be used to load the sample file.
* @param context To be used to load the sample file.
* @throws IOException If reading from the input fails.
* @throws InterruptedException If interrupted while reading from the input.
*/
public static void assertOutput(ExtractorFactory factory, String file, byte[] data,
Instrumentation instrumentation) throws IOException, InterruptedException {
assertOutput(factory.create(), file, data, instrumentation, true, false, false, false);
assertOutput(factory.create(), file, data, instrumentation, true, false, false, true);
assertOutput(factory.create(), file, data, instrumentation, true, false, true, false);
assertOutput(factory.create(), file, data, instrumentation, true, false, true, true);
assertOutput(factory.create(), file, data, instrumentation, true, true, false, false);
assertOutput(factory.create(), file, data, instrumentation, true, true, false, true);
assertOutput(factory.create(), file, data, instrumentation, true, true, true, false);
assertOutput(factory.create(), file, data, instrumentation, true, true, true, true);
assertOutput(factory.create(), file, data, instrumentation, false, false, false, false);
public static void assertOutput(
ExtractorFactory factory, String file, byte[] data, Context context)
throws IOException, InterruptedException {
assertOutput(factory.create(), file, data, context, true, false, false, false);
assertOutput(factory.create(), file, data, context, true, false, false, true);
assertOutput(factory.create(), file, data, context, true, false, true, false);
assertOutput(factory.create(), file, data, context, true, false, true, true);
assertOutput(factory.create(), file, data, context, true, true, false, false);
assertOutput(factory.create(), file, data, context, true, true, false, true);
assertOutput(factory.create(), file, data, context, true, true, true, false);
assertOutput(factory.create(), file, data, context, true, true, true, true);
assertOutput(factory.create(), file, data, context, false, false, false, false);
}
/**
......@@ -107,7 +154,7 @@ public final class ExtractorAsserts {
* @param extractor The {@link Extractor} to be tested.
* @param file The path to the input sample.
* @param data Content of the input file.
* @param instrumentation To be used to load the sample file.
* @param context To be used to load the sample file.
* @param sniffFirst Whether to sniff the data by calling {@link Extractor#sniff(ExtractorInput)}
* prior to consuming it.
* @param simulateIOErrors Whether to simulate IO errors.
......@@ -117,10 +164,16 @@ public final class ExtractorAsserts {
* @throws IOException If reading from the input fails.
* @throws InterruptedException If interrupted while reading from the input.
*/
public static FakeExtractorOutput assertOutput(Extractor extractor, String file, byte[] data,
Instrumentation instrumentation, boolean sniffFirst, boolean simulateIOErrors,
boolean simulateUnknownLength, boolean simulatePartialReads) throws IOException,
InterruptedException {
private static FakeExtractorOutput assertOutput(
Extractor extractor,
String file,
byte[] data,
Context context,
boolean sniffFirst,
boolean simulateIOErrors,
boolean simulateUnknownLength,
boolean simulatePartialReads)
throws IOException, InterruptedException {
FakeExtractorInput input = new FakeExtractorInput.Builder().setData(data)
.setSimulateIOErrors(simulateIOErrors)
.setSimulateUnknownLength(simulateUnknownLength)
......@@ -132,11 +185,10 @@ public final class ExtractorAsserts {
}
FakeExtractorOutput extractorOutput = consumeTestData(extractor, input, 0, true);
if (simulateUnknownLength
&& assetExists(instrumentation, file + UNKNOWN_LENGTH_EXTENSION)) {
extractorOutput.assertOutput(instrumentation, file + UNKNOWN_LENGTH_EXTENSION);
if (simulateUnknownLength && assetExists(context, file + UNKNOWN_LENGTH_EXTENSION)) {
extractorOutput.assertOutput(context, file + UNKNOWN_LENGTH_EXTENSION);
} else {
extractorOutput.assertOutput(instrumentation, file + ".0" + DUMP_EXTENSION);
extractorOutput.assertOutput(context, file + ".0" + DUMP_EXTENSION);
}
SeekMap seekMap = extractorOutput.seekMap;
......@@ -151,7 +203,7 @@ public final class ExtractorAsserts {
}
consumeTestData(extractor, input, timeUs, extractorOutput, false);
extractorOutput.assertOutput(instrumentation, file + '.' + j + DUMP_EXTENSION);
extractorOutput.assertOutput(context, file + '.' + j + DUMP_EXTENSION);
}
}
......@@ -165,16 +217,19 @@ public final class ExtractorAsserts {
* @param factory An {@link ExtractorFactory} which creates instances of the {@link Extractor}
* class which is to be tested.
* @param sampleFile The path to the input sample.
* @param instrumentation To be used to load the sample file.
* @param context To be used to load the sample file.
* @param expectedThrowable Expected {@link Throwable} class.
* @throws IOException If reading from the input fails.
* @throws InterruptedException If interrupted while reading from the input.
* @see #assertThrows(Extractor, byte[], Class, boolean, boolean, boolean)
*/
public static void assertThrows(ExtractorFactory factory, String sampleFile,
Instrumentation instrumentation, Class<? extends Throwable> expectedThrowable)
public static void assertThrows(
ExtractorFactory factory,
String sampleFile,
Context context,
Class<? extends Throwable> expectedThrowable)
throws IOException, InterruptedException {
byte[] fileData = TestUtil.getByteArray(instrumentation, sampleFile);
byte[] fileData = TestUtil.getByteArray(context, sampleFile);
assertThrows(factory, fileData, expectedThrowable);
}
......@@ -190,8 +245,9 @@ public final class ExtractorAsserts {
* @throws InterruptedException If interrupted while reading from the input.
* @see #assertThrows(Extractor, byte[], Class, boolean, boolean, boolean)
*/
public static void assertThrows(ExtractorFactory factory, byte[] fileData,
Class<? extends Throwable> expectedThrowable) throws IOException, InterruptedException {
private static void assertThrows(
ExtractorFactory factory, byte[] fileData, Class<? extends Throwable> expectedThrowable)
throws IOException, InterruptedException {
assertThrows(factory.create(), fileData, expectedThrowable, false, false, false);
assertThrows(factory.create(), fileData, expectedThrowable, true, false, false);
assertThrows(factory.create(), fileData, expectedThrowable, false, true, false);
......@@ -214,10 +270,14 @@ public final class ExtractorAsserts {
* @throws IOException If reading from the input fails.
* @throws InterruptedException If interrupted while reading from the input.
*/
public static void assertThrows(Extractor extractor, byte[] fileData,
Class<? extends Throwable> expectedThrowable, boolean simulateIOErrors,
boolean simulateUnknownLength, boolean simulatePartialReads) throws IOException,
InterruptedException {
private static void assertThrows(
Extractor extractor,
byte[] fileData,
Class<? extends Throwable> expectedThrowable,
boolean simulateIOErrors,
boolean simulateUnknownLength,
boolean simulatePartialReads)
throws IOException, InterruptedException {
FakeExtractorInput input = new FakeExtractorInput.Builder().setData(fileData)
.setSimulateIOErrors(simulateIOErrors)
.setSimulateUnknownLength(simulateUnknownLength)
......@@ -278,13 +338,11 @@ public final class ExtractorAsserts {
}
}
private static boolean assetExists(Instrumentation instrumentation, String fileName)
throws IOException {
private static boolean assetExists(Context context, String fileName) throws IOException {
int i = fileName.lastIndexOf('/');
String path = i >= 0 ? fileName.substring(0, i) : "";
String file = i >= 0 ? fileName.substring(i + 1) : fileName;
return Arrays.asList(instrumentation.getContext().getResources().getAssets().list(path))
.contains(file);
return Arrays.asList(context.getResources().getAssets().list(path)).contains(file);
}
}
......@@ -18,7 +18,7 @@ package com.google.android.exoplayer2.testutil;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import android.app.Instrumentation;
import android.content.Context;
import android.util.SparseArray;
import com.google.android.exoplayer2.extractor.ExtractorOutput;
import com.google.android.exoplayer2.extractor.SeekMap;
......@@ -32,9 +32,9 @@ import java.io.PrintWriter;
public final class FakeExtractorOutput implements ExtractorOutput, Dumper.Dumpable {
/**
* If true, makes {@link #assertOutput(Instrumentation, String)} method write dump result to
* {@code /sdcard/Android/data/apk_package/ + dumpfile} file instead of comparing it with an
* existing file.
* If true, makes {@link #assertOutput(Context, String)} method write dump result to {@code
* /sdcard/Android/data/apk_package/ + dumpfile} file instead of comparing it with an existing
* file.
*/
private static final boolean WRITE_DUMP = false;
......@@ -97,18 +97,18 @@ public final class FakeExtractorOutput implements ExtractorOutput, Dumper.Dumpab
* actual dump will be written to {@code dumpFile}. This new dump file needs to be copied to the
* project, {@code library/src/androidTest/assets} folder manually.
*/
public void assertOutput(Instrumentation instrumentation, String dumpFile) throws IOException {
public void assertOutput(Context context, String dumpFile) throws IOException {
String actual = new Dumper().add(this).toString();
if (WRITE_DUMP) {
File directory = instrumentation.getContext().getExternalFilesDir(null);
File directory = context.getExternalFilesDir(null);
File file = new File(directory, dumpFile);
file.getParentFile().mkdirs();
PrintWriter out = new PrintWriter(file);
out.print(actual);
out.close();
} else {
String expected = TestUtil.getString(instrumentation, dumpFile);
String expected = TestUtil.getString(context, dumpFile);
assertWithMessage(dumpFile).that(actual).isEqualTo(expected);
}
}
......
......@@ -33,6 +33,7 @@ import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Util;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;
......@@ -142,30 +143,38 @@ public class MediaSourceTestRunner {
}
/**
* Calls {@link MediaPeriod#prepare(MediaPeriod.Callback, long)} on the playback thread.
* Calls {@link MediaPeriod#prepare(MediaPeriod.Callback, long)} on the playback thread and blocks
* until the method has been called.
*
* @param mediaPeriod The {@link MediaPeriod} to prepare.
* @param positionUs The position at which to prepare.
* @return A {@link ConditionVariable} that will be opened when preparation completes.
* @return A {@link CountDownLatch} that will be counted down when preparation completes.
*/
public ConditionVariable preparePeriod(final MediaPeriod mediaPeriod, final long positionUs) {
final ConditionVariable preparedCondition = new ConditionVariable();
runOnPlaybackThread(new Runnable() {
@Override
public void run() {
mediaPeriod.prepare(new MediaPeriod.Callback() {
@Override
public void onPrepared(MediaPeriod mediaPeriod) {
preparedCondition.open();
}
public CountDownLatch preparePeriod(final MediaPeriod mediaPeriod, final long positionUs) {
final ConditionVariable prepareCalled = new ConditionVariable();
final CountDownLatch preparedCountDown = new CountDownLatch(1);
runOnPlaybackThread(
new Runnable() {
@Override
public void onContinueLoadingRequested(MediaPeriod source) {
// Do nothing.
public void run() {
mediaPeriod.prepare(
new MediaPeriod.Callback() {
@Override
public void onPrepared(MediaPeriod mediaPeriod) {
preparedCountDown.countDown();
}
@Override
public void onContinueLoadingRequested(MediaPeriod source) {
// Do nothing.
}
},
positionUs);
prepareCalled.open();
}
}, positionUs);
}
});
return preparedCondition;
});
prepareCalled.block();
return preparedCountDown;
}
/**
......@@ -234,10 +243,10 @@ public class MediaSourceTestRunner {
/**
* Creates and releases all periods (including ad periods) defined in the last timeline to be
* returned from {@link #prepareSource()}, {@link #assertTimelineChange()} or
* {@link #assertTimelineChangeBlocking()}.
* returned from {@link #prepareSource()}, {@link #assertTimelineChange()} or {@link
* #assertTimelineChangeBlocking()}.
*/
public void assertPrepareAndReleaseAllPeriods() {
public void assertPrepareAndReleaseAllPeriods() throws InterruptedException {
Timeline.Period period = new Timeline.Period();
for (int i = 0; i < timeline.getPeriodCount(); i++) {
assertPrepareAndReleasePeriod(new MediaPeriodId(i));
......@@ -250,15 +259,16 @@ public class MediaSourceTestRunner {
}
}
private void assertPrepareAndReleasePeriod(MediaPeriodId mediaPeriodId) {
private void assertPrepareAndReleasePeriod(MediaPeriodId mediaPeriodId)
throws InterruptedException {
MediaPeriod mediaPeriod = createPeriod(mediaPeriodId);
ConditionVariable preparedCondition = preparePeriod(mediaPeriod, 0);
assertThat(preparedCondition.block(TIMEOUT_MS)).isTrue();
CountDownLatch preparedCondition = preparePeriod(mediaPeriod, 0);
assertThat(preparedCondition.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)).isTrue();
// MediaSource is supposed to support multiple calls to createPeriod with the same id without an
// intervening call to releasePeriod.
MediaPeriod secondMediaPeriod = createPeriod(mediaPeriodId);
ConditionVariable secondPreparedCondition = preparePeriod(secondMediaPeriod, 0);
assertThat(secondPreparedCondition.block(TIMEOUT_MS)).isTrue();
CountDownLatch secondPreparedCondition = preparePeriod(secondMediaPeriod, 0);
assertThat(secondPreparedCondition.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)).isTrue();
// Release the periods.
releasePeriod(mediaPeriod);
releasePeriod(secondMediaPeriod);
......
......@@ -150,9 +150,8 @@ public class TestUtil {
return context.getResources().getAssets().open(fileName);
}
public static String getString(Instrumentation instrumentation, String fileName)
throws IOException {
return new String(getByteArray(instrumentation, fileName));
public static String getString(Context context, String fileName) throws IOException {
return new String(getByteArray(context, fileName));
}
/**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment