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