Migrate remaining tests to Robolectric

Remaining instrumentation tests either use android.os.Handler or rely on assets.
In the latter case, the tests are difficult to migrate due to differences
between the internal and external build systems, and configuration needed in
Android Studio. In addition, SimpleCacheSpanTest remains as an instrumentation
test because it fails due to a problem with string encoding on the internal
build (and two other tests in its package are kept with it because they depend
on it).

This test removes a dependency from testutils on Mockito, as a different
version of Mockito needs to be used for instrumentation tests vs Robolectric
tests, yet both sets of tests need to rely on testutils. Mockito setup is now
done directly in the tests that need it.

Move OggTestData to testutils so it can be used from both instrumentation and
Robolectric tests.

It may be possible to simplify assertions further using Truth but this is left
for possible later changes.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=167831435
This commit is contained in:
andrewlewis 2017-09-07 01:45:56 -07:00 committed by Oliver Woodman
parent 7053284b02
commit 7c3fe19d3f
53 changed files with 2266 additions and 1320 deletions

View File

@ -23,10 +23,10 @@ import android.test.MoreAsserts;
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.drm.DrmInitData.SchemeData; import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
import com.google.android.exoplayer2.testutil.TestUtil;
import com.google.android.exoplayer2.upstream.HttpDataSource; import com.google.android.exoplayer2.upstream.HttpDataSource;
import java.util.HashMap; import java.util.HashMap;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
/** /**
* Tests {@link OfflineLicenseHelper}. * Tests {@link OfflineLicenseHelper}.
@ -40,7 +40,7 @@ public class OfflineLicenseHelperTest extends InstrumentationTestCase {
@Override @Override
protected void setUp() throws Exception { protected void setUp() throws Exception {
TestUtil.setUpMockito(this); setUpMockito(this);
when(mediaDrm.openSession()).thenReturn(new byte[] {1, 2, 3}); when(mediaDrm.openSession()).thenReturn(new byte[] {1, 2, 3});
offlineLicenseHelper = new OfflineLicenseHelper<>(mediaDrm, mediaDrmCallback, null); offlineLicenseHelper = new OfflineLicenseHelper<>(mediaDrm, mediaDrmCallback, null);
} }
@ -157,4 +157,14 @@ public class OfflineLicenseHelperTest extends InstrumentationTestCase {
new byte[] {1, 4, 7, 0, 3, 6})); new byte[] {1, 4, 7, 0, 3, 6}));
} }
/**
* Sets up Mockito for an instrumentation test.
*/
private static void setUpMockito(InstrumentationTestCase instrumentationTestCase) {
// Workaround for https://code.google.com/p/dexmaker/issues/detail?id=2.
System.setProperty("dexmaker.dexcache",
instrumentationTestCase.getInstrumentation().getTargetContext().getCacheDir().getPath());
MockitoAnnotations.initMocks(instrumentationTestCase);
}
} }

View File

@ -20,6 +20,7 @@ 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.testutil.FakeExtractorInput; import com.google.android.exoplayer2.testutil.FakeExtractorInput;
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;
@ -56,7 +57,7 @@ public final class OggExtractorTest extends InstrumentationTestCase {
public void testSniffVorbis() throws Exception { public void testSniffVorbis() throws Exception {
byte[] data = TestUtil.joinByteArrays( byte[] data = TestUtil.joinByteArrays(
TestData.buildOggHeader(0x02, 0, 1000, 1), OggTestData.buildOggHeader(0x02, 0, 1000, 1),
TestUtil.createByteArray(7), // Laces TestUtil.createByteArray(7), // Laces
new byte[] {0x01, 'v', 'o', 'r', 'b', 'i', 's'}); new byte[] {0x01, 'v', 'o', 'r', 'b', 'i', 's'});
assertTrue(sniff(data)); assertTrue(sniff(data));
@ -64,7 +65,7 @@ public final class OggExtractorTest extends InstrumentationTestCase {
public void testSniffFlac() throws Exception { public void testSniffFlac() throws Exception {
byte[] data = TestUtil.joinByteArrays( byte[] data = TestUtil.joinByteArrays(
TestData.buildOggHeader(0x02, 0, 1000, 1), OggTestData.buildOggHeader(0x02, 0, 1000, 1),
TestUtil.createByteArray(5), // Laces TestUtil.createByteArray(5), // Laces
new byte[] {0x7F, 'F', 'L', 'A', 'C'}); new byte[] {0x7F, 'F', 'L', 'A', 'C'});
assertTrue(sniff(data)); assertTrue(sniff(data));
@ -72,26 +73,26 @@ public final class OggExtractorTest extends InstrumentationTestCase {
public void testSniffFailsOpusFile() throws Exception { public void testSniffFailsOpusFile() throws Exception {
byte[] data = TestUtil.joinByteArrays( byte[] data = TestUtil.joinByteArrays(
TestData.buildOggHeader(0x02, 0, 1000, 0x00), OggTestData.buildOggHeader(0x02, 0, 1000, 0x00),
new byte[] {'O', 'p', 'u', 's'}); new byte[] {'O', 'p', 'u', 's'});
assertFalse(sniff(data)); assertFalse(sniff(data));
} }
public void testSniffFailsInvalidOggHeader() throws Exception { public void testSniffFailsInvalidOggHeader() throws Exception {
byte[] data = TestData.buildOggHeader(0x00, 0, 1000, 0x00); byte[] data = OggTestData.buildOggHeader(0x00, 0, 1000, 0x00);
assertFalse(sniff(data)); assertFalse(sniff(data));
} }
public void testSniffInvalidHeader() throws Exception { public void testSniffInvalidHeader() throws Exception {
byte[] data = TestUtil.joinByteArrays( byte[] data = TestUtil.joinByteArrays(
TestData.buildOggHeader(0x02, 0, 1000, 1), OggTestData.buildOggHeader(0x02, 0, 1000, 1),
TestUtil.createByteArray(7), // Laces TestUtil.createByteArray(7), // Laces
new byte[] {0x7F, 'X', 'o', 'r', 'b', 'i', 's'}); new byte[] {0x7F, 'X', 'o', 'r', 'b', 'i', 's'});
assertFalse(sniff(data)); assertFalse(sniff(data));
} }
public void testSniffFailsEOF() throws Exception { public void testSniffFailsEOF() throws Exception {
byte[] data = TestData.buildOggHeader(0x02, 0, 1000, 0x00); byte[] data = OggTestData.buildOggHeader(0x02, 0, 1000, 0x00);
assertFalse(sniff(data)); assertFalse(sniff(data));
} }

View File

@ -18,6 +18,7 @@ package com.google.android.exoplayer2.extractor.ogg;
import android.test.InstrumentationTestCase; import android.test.InstrumentationTestCase;
import android.test.MoreAsserts; import android.test.MoreAsserts;
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.TestUtil; import com.google.android.exoplayer2.testutil.TestUtil;
import com.google.android.exoplayer2.util.ParsableByteArray; import com.google.android.exoplayer2.util.ParsableByteArray;
import java.io.IOException; import java.io.IOException;
@ -47,20 +48,20 @@ public final class OggPacketTest extends InstrumentationTestCase {
byte[] thirdPacket = TestUtil.buildTestData(256, random); byte[] thirdPacket = TestUtil.buildTestData(256, random);
byte[] fourthPacket = TestUtil.buildTestData(271, random); byte[] fourthPacket = TestUtil.buildTestData(271, random);
FakeExtractorInput input = TestData.createInput( FakeExtractorInput input = OggTestData.createInput(
TestUtil.joinByteArrays( TestUtil.joinByteArrays(
// First page with a single packet. // First page with a single packet.
TestData.buildOggHeader(0x02, 0, 1000, 0x01), OggTestData.buildOggHeader(0x02, 0, 1000, 0x01),
TestUtil.createByteArray(0x08), // Laces TestUtil.createByteArray(0x08), // Laces
firstPacket, firstPacket,
// Second page with a single packet. // Second page with a single packet.
TestData.buildOggHeader(0x00, 16, 1001, 0x02), OggTestData.buildOggHeader(0x00, 16, 1001, 0x02),
TestUtil.createByteArray(0xFF, 0x11), // Laces TestUtil.createByteArray(0xFF, 0x11), // Laces
secondPacket, secondPacket,
// Third page with zero packets. // Third page with zero packets.
TestData.buildOggHeader(0x00, 16, 1002, 0x00), OggTestData.buildOggHeader(0x00, 16, 1002, 0x00),
// Fourth page with two packets. // Fourth page with two packets.
TestData.buildOggHeader(0x04, 128, 1003, 0x04), OggTestData.buildOggHeader(0x04, 128, 1003, 0x04),
TestUtil.createByteArray(0xFF, 0x01, 0xFF, 0x10), // Laces TestUtil.createByteArray(0xFF, 0x01, 0xFF, 0x10), // Laces
thirdPacket, thirdPacket,
fourthPacket), true); fourthPacket), true);
@ -107,9 +108,9 @@ public final class OggPacketTest extends InstrumentationTestCase {
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 = TestData.createInput( FakeExtractorInput input = OggTestData.createInput(
TestUtil.joinByteArrays( TestUtil.joinByteArrays(
TestData.buildOggHeader(0x06, 0, 1000, 0x04), OggTestData.buildOggHeader(0x06, 0, 1000, 0x04),
TestUtil.createByteArray(0xFF, 0x00, 0x00, 0x08), // Laces. TestUtil.createByteArray(0xFF, 0x00, 0x00, 0x08), // Laces.
firstPacket, firstPacket,
secondPacket), true); secondPacket), true);
@ -122,14 +123,14 @@ public final class OggPacketTest extends InstrumentationTestCase {
public void testReadContinuedPacketOverTwoPages() throws Exception { public void testReadContinuedPacketOverTwoPages() throws Exception {
byte[] firstPacket = TestUtil.buildTestData(518); byte[] firstPacket = TestUtil.buildTestData(518);
FakeExtractorInput input = TestData.createInput( FakeExtractorInput input = OggTestData.createInput(
TestUtil.joinByteArrays( TestUtil.joinByteArrays(
// First page. // First page.
TestData.buildOggHeader(0x02, 0, 1000, 0x02), OggTestData.buildOggHeader(0x02, 0, 1000, 0x02),
TestUtil.createByteArray(0xFF, 0xFF), // Laces. TestUtil.createByteArray(0xFF, 0xFF), // Laces.
Arrays.copyOf(firstPacket, 510), Arrays.copyOf(firstPacket, 510),
// Second page (continued packet). // Second page (continued packet).
TestData.buildOggHeader(0x05, 10, 1001, 0x01), OggTestData.buildOggHeader(0x05, 10, 1001, 0x01),
TestUtil.createByteArray(0x08), // Laces. TestUtil.createByteArray(0x08), // Laces.
Arrays.copyOfRange(firstPacket, 510, 510 + 8)), true); Arrays.copyOfRange(firstPacket, 510, 510 + 8)), true);
@ -144,22 +145,22 @@ public final class OggPacketTest extends InstrumentationTestCase {
public void testReadContinuedPacketOverFourPages() throws Exception { public void testReadContinuedPacketOverFourPages() throws Exception {
byte[] firstPacket = TestUtil.buildTestData(1028); byte[] firstPacket = TestUtil.buildTestData(1028);
FakeExtractorInput input = TestData.createInput( FakeExtractorInput input = OggTestData.createInput(
TestUtil.joinByteArrays( TestUtil.joinByteArrays(
// First page. // First page.
TestData.buildOggHeader(0x02, 0, 1000, 0x02), OggTestData.buildOggHeader(0x02, 0, 1000, 0x02),
TestUtil.createByteArray(0xFF, 0xFF), // Laces. TestUtil.createByteArray(0xFF, 0xFF), // Laces.
Arrays.copyOf(firstPacket, 510), Arrays.copyOf(firstPacket, 510),
// Second page (continued packet). // Second page (continued packet).
TestData.buildOggHeader(0x01, 10, 1001, 0x01), OggTestData.buildOggHeader(0x01, 10, 1001, 0x01),
TestUtil.createByteArray(0xFF), // Laces. TestUtil.createByteArray(0xFF), // Laces.
Arrays.copyOfRange(firstPacket, 510, 510 + 255), Arrays.copyOfRange(firstPacket, 510, 510 + 255),
// Third page (continued packet). // Third page (continued packet).
TestData.buildOggHeader(0x01, 10, 1002, 0x01), OggTestData.buildOggHeader(0x01, 10, 1002, 0x01),
TestUtil.createByteArray(0xFF), // Laces. TestUtil.createByteArray(0xFF), // Laces.
Arrays.copyOfRange(firstPacket, 510 + 255, 510 + 255 + 255), Arrays.copyOfRange(firstPacket, 510 + 255, 510 + 255 + 255),
// Fourth page (continued packet). // Fourth page (continued packet).
TestData.buildOggHeader(0x05, 10, 1003, 0x01), OggTestData.buildOggHeader(0x05, 10, 1003, 0x01),
TestUtil.createByteArray(0x08), // Laces. TestUtil.createByteArray(0x08), // Laces.
Arrays.copyOfRange(firstPacket, 510 + 255 + 255, 510 + 255 + 255 + 8)), true); Arrays.copyOfRange(firstPacket, 510 + 255 + 255, 510 + 255 + 255 + 8)), true);
@ -174,10 +175,10 @@ public final class OggPacketTest extends InstrumentationTestCase {
public void testReadDiscardContinuedPacketAtStart() throws Exception { public void testReadDiscardContinuedPacketAtStart() throws Exception {
byte[] pageBody = TestUtil.buildTestData(256 + 8); byte[] pageBody = TestUtil.buildTestData(256 + 8);
FakeExtractorInput input = TestData.createInput( FakeExtractorInput input = OggTestData.createInput(
TestUtil.joinByteArrays( TestUtil.joinByteArrays(
// Page with a continued packet at start. // Page with a continued packet at start.
TestData.buildOggHeader(0x01, 10, 1001, 0x03), OggTestData.buildOggHeader(0x01, 10, 1001, 0x03),
TestUtil.createByteArray(255, 1, 8), // Laces. TestUtil.createByteArray(255, 1, 8), // Laces.
pageBody), true); pageBody), true);
@ -191,15 +192,15 @@ public final class OggPacketTest extends InstrumentationTestCase {
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 = TestData.createInput( FakeExtractorInput input = OggTestData.createInput(
TestUtil.joinByteArrays( TestUtil.joinByteArrays(
TestData.buildOggHeader(0x02, 0, 1000, 0x01), OggTestData.buildOggHeader(0x02, 0, 1000, 0x01),
TestUtil.createByteArray(0x08), // Laces. TestUtil.createByteArray(0x08), // Laces.
firstPacket, firstPacket,
TestData.buildOggHeader(0x04, 0, 1001, 0x03), OggTestData.buildOggHeader(0x04, 0, 1001, 0x03),
TestUtil.createByteArray(0x08, 0x00, 0x00), // Laces. TestUtil.createByteArray(0x08, 0x00, 0x00), // Laces.
secondPacket, secondPacket,
TestData.buildOggHeader(0x04, 0, 1002, 0x03), OggTestData.buildOggHeader(0x04, 0, 1002, 0x03),
TestUtil.createByteArray(0x08, 0x00, 0x00), // Laces. TestUtil.createByteArray(0x08, 0x00, 0x00), // Laces.
thirdPacket), true); thirdPacket), true);

View File

@ -15,6 +15,7 @@
*/ */
package com.google.android.exoplayer2.extractor.ogg; package com.google.android.exoplayer2.extractor.ogg;
import com.google.android.exoplayer2.testutil.OggTestData;
import com.google.android.exoplayer2.testutil.TestUtil; import com.google.android.exoplayer2.testutil.TestUtil;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Random; import java.util.Random;
@ -68,7 +69,7 @@ import junit.framework.Assert;
} }
granule += random.nextInt(MAX_GRANULES_IN_PAGE - 1) + 1; granule += random.nextInt(MAX_GRANULES_IN_PAGE - 1) + 1;
int pageSegmentCount = random.nextInt(MAX_SEGMENT_COUNT); int pageSegmentCount = random.nextInt(MAX_SEGMENT_COUNT);
byte[] header = TestData.buildOggHeader(headerType, granule, 0, pageSegmentCount); byte[] header = OggTestData.buildOggHeader(headerType, granule, 0, pageSegmentCount);
fileData.add(header); fileData.add(header);
fileSize += header.length; fileSize += header.length;

View File

@ -1,139 +0,0 @@
/*
* 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.
*/
package com.google.android.exoplayer2.extractor.ogg;
import com.google.android.exoplayer2.testutil.TestUtil;
import junit.framework.TestCase;
/**
* Unit test for {@link VorbisBitArray}.
*/
public final class VorbisBitArrayTest extends TestCase {
public void testReadBit() {
VorbisBitArray bitArray = new VorbisBitArray(TestUtil.createByteArray(0x5c, 0x50));
assertFalse(bitArray.readBit());
assertFalse(bitArray.readBit());
assertTrue(bitArray.readBit());
assertTrue(bitArray.readBit());
assertTrue(bitArray.readBit());
assertFalse(bitArray.readBit());
assertTrue(bitArray.readBit());
assertFalse(bitArray.readBit());
assertFalse(bitArray.readBit());
assertFalse(bitArray.readBit());
assertFalse(bitArray.readBit());
assertFalse(bitArray.readBit());
assertTrue(bitArray.readBit());
assertFalse(bitArray.readBit());
assertTrue(bitArray.readBit());
assertFalse(bitArray.readBit());
}
public void testSkipBits() {
VorbisBitArray bitArray = new VorbisBitArray(TestUtil.createByteArray(0xF0, 0x0F));
bitArray.skipBits(10);
assertEquals(10, bitArray.getPosition());
assertTrue(bitArray.readBit());
assertTrue(bitArray.readBit());
assertFalse(bitArray.readBit());
bitArray.skipBits(1);
assertEquals(14, bitArray.getPosition());
assertFalse(bitArray.readBit());
assertFalse(bitArray.readBit());
}
public void testGetPosition() throws Exception {
VorbisBitArray bitArray = new VorbisBitArray(TestUtil.createByteArray(0xF0, 0x0F));
assertEquals(0, bitArray.getPosition());
bitArray.readBit();
assertEquals(1, bitArray.getPosition());
bitArray.readBit();
bitArray.readBit();
bitArray.skipBits(4);
assertEquals(7, bitArray.getPosition());
}
public void testSetPosition() throws Exception {
VorbisBitArray bitArray = new VorbisBitArray(TestUtil.createByteArray(0xF0, 0x0F));
assertEquals(0, bitArray.getPosition());
bitArray.setPosition(4);
assertEquals(4, bitArray.getPosition());
bitArray.setPosition(15);
assertFalse(bitArray.readBit());
}
public void testReadInt32() {
VorbisBitArray bitArray = new VorbisBitArray(TestUtil.createByteArray(0xF0, 0x0F, 0xF0, 0x0F));
assertEquals(0x0FF00FF0, bitArray.readBits(32));
bitArray = new VorbisBitArray(TestUtil.createByteArray(0x0F, 0xF0, 0x0F, 0xF0));
assertEquals(0xF00FF00F, bitArray.readBits(32));
}
public void testReadBits() throws Exception {
VorbisBitArray bitArray = new VorbisBitArray(TestUtil.createByteArray(0x03, 0x22));
assertEquals(3, bitArray.readBits(2));
bitArray.skipBits(6);
assertEquals(2, bitArray.readBits(2));
bitArray.skipBits(2);
assertEquals(2, bitArray.readBits(2));
bitArray.reset();
assertEquals(0x2203, bitArray.readBits(16));
}
public void testRead4BitsBeyondBoundary() throws Exception {
VorbisBitArray bitArray = new VorbisBitArray(TestUtil.createByteArray(0x2e, 0x10));
assertEquals(0x2e, bitArray.readBits(7));
assertEquals(7, bitArray.getPosition());
assertEquals(0x0, bitArray.readBits(4));
}
public void testReadBitsBeyondByteBoundaries() throws Exception {
VorbisBitArray bitArray = new VorbisBitArray(TestUtil.createByteArray(0xFF, 0x0F, 0xFF, 0x0F));
assertEquals(0x0FFF0FFF, bitArray.readBits(32));
bitArray.reset();
bitArray.skipBits(4);
assertEquals(0xF0FF, bitArray.readBits(16));
bitArray.reset();
bitArray.skipBits(6);
assertEquals(0xc3F, bitArray.readBits(12));
bitArray.reset();
bitArray.skipBits(6);
assertTrue(bitArray.readBit());
assertTrue(bitArray.readBit());
assertEquals(24, bitArray.bitsLeft());
bitArray.reset();
bitArray.skipBits(10);
assertEquals(3, bitArray.readBits(5));
assertEquals(15, bitArray.getPosition());
}
public void testReadBitsIllegalLengths() throws Exception {
VorbisBitArray bitArray = new VorbisBitArray(TestUtil.createByteArray(0x03, 0x22, 0x30));
// reading zero bits gets 0 without advancing position
// (like a zero-bit read is defined to yield zer0)
assertEquals(0, bitArray.readBits(0));
assertEquals(0, bitArray.getPosition());
bitArray.readBit();
assertEquals(1, bitArray.getPosition());
}
}

View File

@ -1,104 +0,0 @@
/*
* 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.
*/
package com.google.android.exoplayer2.extractor.ogg;
import com.google.android.exoplayer2.extractor.ExtractorInput;
import com.google.android.exoplayer2.extractor.ogg.VorbisReader.VorbisSetup;
import com.google.android.exoplayer2.testutil.FakeExtractorInput;
import com.google.android.exoplayer2.testutil.FakeExtractorInput.SimulatedIOException;
import com.google.android.exoplayer2.util.ParsableByteArray;
import java.io.IOException;
import junit.framework.TestCase;
/**
* Unit test for {@link VorbisReader}.
*/
public final class VorbisReaderTest extends TestCase {
public void testReadBits() throws Exception {
assertEquals(0, VorbisReader.readBits((byte) 0x00, 2, 2));
assertEquals(1, VorbisReader.readBits((byte) 0x02, 1, 1));
assertEquals(15, VorbisReader.readBits((byte) 0xF0, 4, 4));
assertEquals(1, VorbisReader.readBits((byte) 0x80, 1, 7));
}
public void testAppendNumberOfSamples() throws Exception {
ParsableByteArray buffer = new ParsableByteArray(4);
buffer.setLimit(0);
VorbisReader.appendNumberOfSamples(buffer, 0x01234567);
assertEquals(4, buffer.limit());
assertEquals(0x67, buffer.data[0]);
assertEquals(0x45, buffer.data[1]);
assertEquals(0x23, buffer.data[2]);
assertEquals(0x01, buffer.data[3]);
}
public void testReadSetupHeadersWithIOExceptions() throws IOException, InterruptedException {
byte[] data = TestData.getVorbisHeaderPages();
ExtractorInput input = new FakeExtractorInput.Builder().setData(data).setSimulateIOErrors(true)
.setSimulateUnknownLength(true).setSimulatePartialReads(true).build();
VorbisReader reader = new VorbisReader();
VorbisReader.VorbisSetup vorbisSetup = readSetupHeaders(reader, input);
assertNotNull(vorbisSetup.idHeader);
assertNotNull(vorbisSetup.commentHeader);
assertNotNull(vorbisSetup.setupHeaderData);
assertNotNull(vorbisSetup.modes);
assertEquals(45, vorbisSetup.commentHeader.length);
assertEquals(30, vorbisSetup.idHeader.data.length);
assertEquals(3597, vorbisSetup.setupHeaderData.length);
assertEquals(-1, vorbisSetup.idHeader.bitrateMax);
assertEquals(-1, vorbisSetup.idHeader.bitrateMin);
assertEquals(66666, vorbisSetup.idHeader.bitrateNominal);
assertEquals(512, vorbisSetup.idHeader.blockSize0);
assertEquals(1024, vorbisSetup.idHeader.blockSize1);
assertEquals(2, vorbisSetup.idHeader.channels);
assertTrue(vorbisSetup.idHeader.framingFlag);
assertEquals(22050, vorbisSetup.idHeader.sampleRate);
assertEquals(0, vorbisSetup.idHeader.version);
assertEquals("Xiph.Org libVorbis I 20030909", vorbisSetup.commentHeader.vendor);
assertEquals(1, vorbisSetup.iLogModes);
assertEquals(data[data.length - 1],
vorbisSetup.setupHeaderData[vorbisSetup.setupHeaderData.length - 1]);
assertFalse(vorbisSetup.modes[0].blockFlag);
assertTrue(vorbisSetup.modes[1].blockFlag);
}
private static VorbisSetup readSetupHeaders(VorbisReader reader, ExtractorInput input)
throws IOException, InterruptedException {
OggPacket oggPacket = new OggPacket();
while (true) {
try {
if (!oggPacket.populate(input)) {
fail();
}
VorbisSetup vorbisSetup = reader.readSetupHeaders(oggPacket.getPayload());
if (vorbisSetup != null) {
return vorbisSetup;
}
} catch (SimulatedIOException e) {
// Ignore.
}
}
}
}

View File

@ -1,126 +0,0 @@
/*
* 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.
*/
package com.google.android.exoplayer2.extractor.ogg;
import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.util.ParsableByteArray;
import junit.framework.TestCase;
/**
* Unit test for {@link VorbisUtil}.
*/
public final class VorbisUtilTest extends TestCase {
public void testILog() throws Exception {
assertEquals(0, VorbisUtil.iLog(0));
assertEquals(1, VorbisUtil.iLog(1));
assertEquals(2, VorbisUtil.iLog(2));
assertEquals(2, VorbisUtil.iLog(3));
assertEquals(3, VorbisUtil.iLog(4));
assertEquals(3, VorbisUtil.iLog(5));
assertEquals(4, VorbisUtil.iLog(8));
assertEquals(0, VorbisUtil.iLog(-1));
assertEquals(0, VorbisUtil.iLog(-122));
}
public void testReadIdHeader() throws Exception {
byte[] data = TestData.getIdentificationHeaderData();
ParsableByteArray headerData = new ParsableByteArray(data, data.length);
VorbisUtil.VorbisIdHeader vorbisIdHeader =
VorbisUtil.readVorbisIdentificationHeader(headerData);
assertEquals(22050, vorbisIdHeader.sampleRate);
assertEquals(0, vorbisIdHeader.version);
assertTrue(vorbisIdHeader.framingFlag);
assertEquals(2, vorbisIdHeader.channels);
assertEquals(512, vorbisIdHeader.blockSize0);
assertEquals(1024, vorbisIdHeader.blockSize1);
assertEquals(-1, vorbisIdHeader.bitrateMax);
assertEquals(-1, vorbisIdHeader.bitrateMin);
assertEquals(66666, vorbisIdHeader.bitrateNominal);
assertEquals(66666, vorbisIdHeader.getApproximateBitrate());
}
public void testReadCommentHeader() throws ParserException {
byte[] data = TestData.getCommentHeaderDataUTF8();
ParsableByteArray headerData = new ParsableByteArray(data, data.length);
VorbisUtil.CommentHeader commentHeader = VorbisUtil.readVorbisCommentHeader(headerData);
assertEquals("Xiph.Org libVorbis I 20120203 (Omnipresent)", commentHeader.vendor);
assertEquals(3, commentHeader.comments.length);
assertEquals("ALBUM=äö", commentHeader.comments[0]);
assertEquals("TITLE=A sample song", commentHeader.comments[1]);
assertEquals("ARTIST=Google", commentHeader.comments[2]);
}
public void testReadVorbisModes() throws ParserException {
byte[] data = TestData.getSetupHeaderData();
ParsableByteArray headerData = new ParsableByteArray(data, data.length);
VorbisUtil.Mode[] modes = VorbisUtil.readVorbisModes(headerData, 2);
assertEquals(2, modes.length);
assertEquals(false, modes[0].blockFlag);
assertEquals(0, modes[0].mapping);
assertEquals(0, modes[0].transformType);
assertEquals(0, modes[0].windowType);
assertEquals(true, modes[1].blockFlag);
assertEquals(1, modes[1].mapping);
assertEquals(0, modes[1].transformType);
assertEquals(0, modes[1].windowType);
}
public void testVerifyVorbisHeaderCapturePattern() throws ParserException {
ParsableByteArray header = new ParsableByteArray(
new byte[] {0x01, 'v', 'o', 'r', 'b', 'i', 's'});
assertEquals(true, VorbisUtil.verifyVorbisHeaderCapturePattern(0x01, header, false));
}
public void testVerifyVorbisHeaderCapturePatternInvalidHeader() {
ParsableByteArray header = new ParsableByteArray(
new byte[] {0x01, 'v', 'o', 'r', 'b', 'i', 's'});
try {
VorbisUtil.verifyVorbisHeaderCapturePattern(0x99, header, false);
fail();
} catch (ParserException e) {
assertEquals("expected header type 99", e.getMessage());
}
}
public void testVerifyVorbisHeaderCapturePatternInvalidHeaderQuite() throws ParserException {
ParsableByteArray header = new ParsableByteArray(
new byte[] {0x01, 'v', 'o', 'r', 'b', 'i', 's'});
assertFalse(VorbisUtil.verifyVorbisHeaderCapturePattern(0x99, header, true));
}
public void testVerifyVorbisHeaderCapturePatternInvalidPattern() {
ParsableByteArray header = new ParsableByteArray(
new byte[] {0x01, 'x', 'v', 'o', 'r', 'b', 'i', 's'});
try {
VorbisUtil.verifyVorbisHeaderCapturePattern(0x01, header, false);
fail();
} catch (ParserException e) {
assertEquals("expected characters 'vorbis'", e.getMessage());
}
}
public void testVerifyVorbisHeaderCapturePatternQuiteInvalidPatternQuite()
throws ParserException {
ParsableByteArray header = new ParsableByteArray(
new byte[] {0x01, 'x', 'v', 'o', 'r', 'b', 'i', 's'});
assertFalse(VorbisUtil.verifyVorbisHeaderCapturePattern(0x01, header, true));
}
}

View File

@ -1,132 +0,0 @@
/*
* 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.
*/
package com.google.android.exoplayer2.text.ttml;
import android.graphics.Color;
import android.test.InstrumentationTestCase;
/**
* Unit test for {@link TtmlStyle}.
*/
public final class TtmlStyleTest extends InstrumentationTestCase {
private static final String FONT_FAMILY = "serif";
private static final String ID = "id";
public static final int FOREGROUND_COLOR = Color.WHITE;
public static final int BACKGROUND_COLOR = Color.BLACK;
private TtmlStyle style;
@Override
public void setUp() throws Exception {
super.setUp();
style = new TtmlStyle();
}
public void testInheritStyle() {
style.inherit(createAncestorStyle());
assertNull("id must not be inherited", style.getId());
assertTrue(style.isUnderline());
assertTrue(style.isLinethrough());
assertEquals(TtmlStyle.STYLE_BOLD_ITALIC, style.getStyle());
assertEquals(FONT_FAMILY, style.getFontFamily());
assertEquals(Color.WHITE, style.getFontColor());
assertFalse("do not inherit backgroundColor", style.hasBackgroundColor());
}
public void testChainStyle() {
style.chain(createAncestorStyle());
assertNull("id must not be inherited", style.getId());
assertTrue(style.isUnderline());
assertTrue(style.isLinethrough());
assertEquals(TtmlStyle.STYLE_BOLD_ITALIC, style.getStyle());
assertEquals(FONT_FAMILY, style.getFontFamily());
assertEquals(FOREGROUND_COLOR, style.getFontColor());
// do inherit backgroundColor when chaining
assertEquals("do not inherit backgroundColor when chaining",
BACKGROUND_COLOR, style.getBackgroundColor());
}
private TtmlStyle createAncestorStyle() {
TtmlStyle ancestor = new TtmlStyle();
ancestor.setId(ID);
ancestor.setItalic(true);
ancestor.setBold(true);
ancestor.setBackgroundColor(BACKGROUND_COLOR);
ancestor.setFontColor(FOREGROUND_COLOR);
ancestor.setLinethrough(true);
ancestor.setUnderline(true);
ancestor.setFontFamily(FONT_FAMILY);
return ancestor;
}
public void testStyle() {
assertEquals(TtmlStyle.UNSPECIFIED, style.getStyle());
style.setItalic(true);
assertEquals(TtmlStyle.STYLE_ITALIC, style.getStyle());
style.setBold(true);
assertEquals(TtmlStyle.STYLE_BOLD_ITALIC, style.getStyle());
style.setItalic(false);
assertEquals(TtmlStyle.STYLE_BOLD, style.getStyle());
style.setBold(false);
assertEquals(TtmlStyle.STYLE_NORMAL, style.getStyle());
}
public void testLinethrough() {
assertFalse(style.isLinethrough());
style.setLinethrough(true);
assertTrue(style.isLinethrough());
style.setLinethrough(false);
assertFalse(style.isLinethrough());
}
public void testUnderline() {
assertFalse(style.isUnderline());
style.setUnderline(true);
assertTrue(style.isUnderline());
style.setUnderline(false);
assertFalse(style.isUnderline());
}
public void testFontFamily() {
assertNull(style.getFontFamily());
style.setFontFamily(FONT_FAMILY);
assertEquals(FONT_FAMILY, style.getFontFamily());
style.setFontFamily(null);
assertNull(style.getFontFamily());
}
public void testColor() {
assertFalse(style.hasFontColor());
style.setFontColor(Color.BLACK);
assertEquals(Color.BLACK, style.getFontColor());
assertTrue(style.hasFontColor());
}
public void testBackgroundColor() {
assertFalse(style.hasBackgroundColor());
style.setBackgroundColor(Color.BLACK);
assertEquals(Color.BLACK, style.getBackgroundColor());
assertTrue(style.hasBackgroundColor());
}
public void testId() {
assertNull(style.getId());
style.setId(ID);
assertEquals(ID, style.getId());
style.setId(null);
assertNull(style.getId());
}
}

View File

@ -17,11 +17,11 @@ package com.google.android.exoplayer2.upstream.cache;
import android.test.InstrumentationTestCase; import android.test.InstrumentationTestCase;
import com.google.android.exoplayer2.extractor.ChunkIndex; import com.google.android.exoplayer2.extractor.ChunkIndex;
import com.google.android.exoplayer2.testutil.TestUtil;
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.IOException; import java.io.IOException;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
/** /**
* Tests for {@link CachedRegionTracker}. * Tests for {@link CachedRegionTracker}.
@ -46,10 +46,9 @@ public final class CachedRegionTrackerTest extends InstrumentationTestCase {
@Override @Override
protected void setUp() throws Exception { protected void setUp() throws Exception {
TestUtil.setUpMockito(this); setUpMockito(this);
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(getInstrumentation().getContext(), "ExoPlayerTest");
index = new CachedContentIndex(cacheDir); index = new CachedContentIndex(cacheDir);
} }
@ -124,4 +123,14 @@ public final class CachedRegionTrackerTest extends InstrumentationTestCase {
return SimpleCacheSpanTest.createCacheSpan(index, cacheDir, CACHE_KEY, position, length, 0); return SimpleCacheSpanTest.createCacheSpan(index, cacheDir, CACHE_KEY, position, length, 0);
} }
/**
* Sets up Mockito for an instrumentation test.
*/
private static void setUpMockito(InstrumentationTestCase instrumentationTestCase) {
// Workaround for https://code.google.com/p/dexmaker/issues/detail?id=2.
System.setProperty("dexmaker.dexcache",
instrumentationTestCase.getInstrumentation().getTargetContext().getCacheDir().getPath());
MockitoAnnotations.initMocks(instrumentationTestCase);
}
} }

View File

@ -16,20 +16,27 @@
package com.google.android.exoplayer2.drm; package com.google.android.exoplayer2.drm;
import static com.google.android.exoplayer2.C.PLAYREADY_UUID; import static com.google.android.exoplayer2.C.PLAYREADY_UUID;
import static com.google.android.exoplayer2.C.UUID_NIL;
import static com.google.android.exoplayer2.C.WIDEVINE_UUID; import static com.google.android.exoplayer2.C.WIDEVINE_UUID;
import static com.google.android.exoplayer2.util.MimeTypes.VIDEO_MP4; import static com.google.android.exoplayer2.util.MimeTypes.VIDEO_MP4;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import android.os.Parcel; import android.os.Parcel;
import android.test.MoreAsserts;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.drm.DrmInitData.SchemeData; import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
import com.google.android.exoplayer2.testutil.TestUtil; import com.google.android.exoplayer2.testutil.TestUtil;
import junit.framework.TestCase; import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/** /**
* Unit test for {@link DrmInitData}. * Unit test for {@link DrmInitData}.
*/ */
public class DrmInitDataTest extends TestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public class DrmInitDataTest {
private static final SchemeData DATA_1 = new SchemeData(WIDEVINE_UUID, VIDEO_MP4, private static final SchemeData DATA_1 = new SchemeData(WIDEVINE_UUID, VIDEO_MP4,
TestUtil.buildTestData(128, 1 /* data seed */)); TestUtil.buildTestData(128, 1 /* data seed */));
@ -42,6 +49,7 @@ public class DrmInitDataTest extends TestCase {
private static final SchemeData DATA_UNIVERSAL = new SchemeData(C.UUID_NIL, VIDEO_MP4, private static final SchemeData DATA_UNIVERSAL = new SchemeData(C.UUID_NIL, VIDEO_MP4,
TestUtil.buildTestData(128, 3 /* data seed */)); TestUtil.buildTestData(128, 3 /* data seed */));
@Test
public void testParcelable() { public void testParcelable() {
DrmInitData drmInitDataToParcel = new DrmInitData(DATA_1, DATA_2); DrmInitData drmInitDataToParcel = new DrmInitData(DATA_1, DATA_2);
@ -50,69 +58,72 @@ public class DrmInitDataTest extends TestCase {
parcel.setDataPosition(0); parcel.setDataPosition(0);
DrmInitData drmInitDataFromParcel = DrmInitData.CREATOR.createFromParcel(parcel); DrmInitData drmInitDataFromParcel = DrmInitData.CREATOR.createFromParcel(parcel);
assertEquals(drmInitDataToParcel, drmInitDataFromParcel); assertThat(drmInitDataFromParcel).isEqualTo(drmInitDataToParcel);
parcel.recycle(); parcel.recycle();
} }
@Test
public void testEquals() { public void testEquals() {
DrmInitData drmInitData = new DrmInitData(DATA_1, DATA_2); DrmInitData drmInitData = new DrmInitData(DATA_1, DATA_2);
// Basic non-referential equality test. // Basic non-referential equality test.
DrmInitData testInitData = new DrmInitData(DATA_1, DATA_2); DrmInitData testInitData = new DrmInitData(DATA_1, DATA_2);
assertEquals(drmInitData, testInitData); assertThat(testInitData).isEqualTo(drmInitData);
assertEquals(drmInitData.hashCode(), testInitData.hashCode()); assertThat(testInitData.hashCode()).isEqualTo(drmInitData.hashCode());
// Basic non-referential equality test with non-referential scheme data. // Basic non-referential equality test with non-referential scheme data.
testInitData = new DrmInitData(DATA_1B, DATA_2B); testInitData = new DrmInitData(DATA_1B, DATA_2B);
assertEquals(drmInitData, testInitData); assertThat(testInitData).isEqualTo(drmInitData);
assertEquals(drmInitData.hashCode(), testInitData.hashCode()); assertThat(testInitData.hashCode()).isEqualTo(drmInitData.hashCode());
// Passing the scheme data in reverse order shouldn't affect equality. // Passing the scheme data in reverse order shouldn't affect equality.
testInitData = new DrmInitData(DATA_2, DATA_1); testInitData = new DrmInitData(DATA_2, DATA_1);
assertEquals(drmInitData, testInitData); assertThat(testInitData).isEqualTo(drmInitData);
assertEquals(drmInitData.hashCode(), testInitData.hashCode()); assertThat(testInitData.hashCode()).isEqualTo(drmInitData.hashCode());
// Ditto. // Ditto.
testInitData = new DrmInitData(DATA_2B, DATA_1B); testInitData = new DrmInitData(DATA_2B, DATA_1B);
assertEquals(drmInitData, testInitData); assertThat(testInitData).isEqualTo(drmInitData);
assertEquals(drmInitData.hashCode(), testInitData.hashCode()); assertThat(testInitData.hashCode()).isEqualTo(drmInitData.hashCode());
// Different number of tuples should affect equality. // Different number of tuples should affect equality.
testInitData = new DrmInitData(DATA_1); testInitData = new DrmInitData(DATA_1);
MoreAsserts.assertNotEqual(drmInitData, testInitData); assertThat(drmInitData).isNotEqualTo(testInitData);
// Different data in one of the tuples should affect equality. // Different data in one of the tuples should affect equality.
testInitData = new DrmInitData(DATA_1, DATA_UNIVERSAL); testInitData = new DrmInitData(DATA_1, DATA_UNIVERSAL);
MoreAsserts.assertNotEqual(drmInitData, testInitData); assertThat(testInitData).isNotEqualTo(drmInitData);
} }
@Test
public void testGet() { public void testGet() {
// Basic matching. // Basic matching.
DrmInitData testInitData = new DrmInitData(DATA_1, DATA_2); DrmInitData testInitData = new DrmInitData(DATA_1, DATA_2);
assertEquals(DATA_1, testInitData.get(WIDEVINE_UUID)); assertThat(testInitData.get(WIDEVINE_UUID)).isEqualTo(DATA_1);
assertEquals(DATA_2, testInitData.get(PLAYREADY_UUID)); assertThat(testInitData.get(PLAYREADY_UUID)).isEqualTo(DATA_2);
assertNull(testInitData.get(C.UUID_NIL)); assertThat(testInitData.get(UUID_NIL)).isNull();
// Basic matching including universal data. // Basic matching including universal data.
testInitData = new DrmInitData(DATA_1, DATA_2, DATA_UNIVERSAL); testInitData = new DrmInitData(DATA_1, DATA_2, DATA_UNIVERSAL);
assertEquals(DATA_1, testInitData.get(WIDEVINE_UUID)); assertThat(testInitData.get(WIDEVINE_UUID)).isEqualTo(DATA_1);
assertEquals(DATA_2, testInitData.get(PLAYREADY_UUID)); assertThat(testInitData.get(PLAYREADY_UUID)).isEqualTo(DATA_2);
assertEquals(DATA_UNIVERSAL, testInitData.get(C.UUID_NIL)); assertThat(testInitData.get(UUID_NIL)).isEqualTo(DATA_UNIVERSAL);
// Passing the scheme data in reverse order shouldn't affect equality. // Passing the scheme data in reverse order shouldn't affect equality.
testInitData = new DrmInitData(DATA_UNIVERSAL, DATA_2, DATA_1); testInitData = new DrmInitData(DATA_UNIVERSAL, DATA_2, DATA_1);
assertEquals(DATA_1, testInitData.get(WIDEVINE_UUID)); assertThat(testInitData.get(WIDEVINE_UUID)).isEqualTo(DATA_1);
assertEquals(DATA_2, testInitData.get(PLAYREADY_UUID)); assertThat(testInitData.get(PLAYREADY_UUID)).isEqualTo(DATA_2);
assertEquals(DATA_UNIVERSAL, testInitData.get(C.UUID_NIL)); assertThat(testInitData.get(UUID_NIL)).isEqualTo(DATA_UNIVERSAL);
// Universal data should be returned in the absence of a specific match. // Universal data should be returned in the absence of a specific match.
testInitData = new DrmInitData(DATA_1, DATA_UNIVERSAL); testInitData = new DrmInitData(DATA_1, DATA_UNIVERSAL);
assertEquals(DATA_1, testInitData.get(WIDEVINE_UUID)); assertThat(testInitData.get(WIDEVINE_UUID)).isEqualTo(DATA_1);
assertEquals(DATA_UNIVERSAL, testInitData.get(PLAYREADY_UUID)); assertThat(testInitData.get(PLAYREADY_UUID)).isEqualTo(DATA_UNIVERSAL);
assertEquals(DATA_UNIVERSAL, testInitData.get(C.UUID_NIL)); assertThat(testInitData.get(UUID_NIL)).isEqualTo(DATA_UNIVERSAL);
} }
@Test
public void testDuplicateSchemeDataRejected() { public void testDuplicateSchemeDataRejected() {
try { try {
new DrmInitData(DATA_1, DATA_1); new DrmInitData(DATA_1, DATA_1);
@ -136,18 +147,19 @@ public class DrmInitDataTest extends TestCase {
} }
} }
@Test
public void testSchemeDataMatches() { public void testSchemeDataMatches() {
assertTrue(DATA_1.matches(WIDEVINE_UUID)); assertThat(DATA_1.matches(WIDEVINE_UUID)).isTrue();
assertFalse(DATA_1.matches(PLAYREADY_UUID)); assertThat(DATA_1.matches(PLAYREADY_UUID)).isFalse();
assertFalse(DATA_2.matches(C.UUID_NIL)); assertThat(DATA_2.matches(UUID_NIL)).isFalse();
assertFalse(DATA_2.matches(WIDEVINE_UUID)); assertThat(DATA_2.matches(WIDEVINE_UUID)).isFalse();
assertTrue(DATA_2.matches(PLAYREADY_UUID)); assertThat(DATA_2.matches(PLAYREADY_UUID)).isTrue();
assertFalse(DATA_2.matches(C.UUID_NIL)); assertThat(DATA_2.matches(UUID_NIL)).isFalse();
assertTrue(DATA_UNIVERSAL.matches(WIDEVINE_UUID)); assertThat(DATA_UNIVERSAL.matches(WIDEVINE_UUID)).isTrue();
assertTrue(DATA_UNIVERSAL.matches(PLAYREADY_UUID)); assertThat(DATA_UNIVERSAL.matches(PLAYREADY_UUID)).isTrue();
assertTrue(DATA_UNIVERSAL.matches(C.UUID_NIL)); assertThat(DATA_UNIVERSAL.matches(UUID_NIL)).isTrue();
} }
} }

View File

@ -15,6 +15,12 @@
*/ */
package com.google.android.exoplayer2.extractor; package com.google.android.exoplayer2.extractor;
import static com.google.android.exoplayer2.C.RESULT_END_OF_INPUT;
import static com.google.common.truth.Truth.assertThat;
import static java.util.Arrays.copyOf;
import static java.util.Arrays.copyOfRange;
import static org.junit.Assert.fail;
import android.net.Uri; import android.net.Uri;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.testutil.FakeDataSource; import com.google.android.exoplayer2.testutil.FakeDataSource;
@ -22,42 +28,50 @@ import com.google.android.exoplayer2.upstream.DataSpec;
import java.io.EOFException; import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import junit.framework.TestCase; import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/** /**
* Test for {@link DefaultExtractorInput}. * Test for {@link DefaultExtractorInput}.
*/ */
public class DefaultExtractorInputTest extends TestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public class DefaultExtractorInputTest {
private static final String TEST_URI = "http://www.google.com"; private static final String TEST_URI = "http://www.google.com";
private static final byte[] TEST_DATA = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8}; private static final byte[] TEST_DATA = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8};
private static final int LARGE_TEST_DATA_LENGTH = 8192; private static final int LARGE_TEST_DATA_LENGTH = 8192;
@Test
public void testInitialPosition() throws Exception { public void testInitialPosition() throws Exception {
FakeDataSource testDataSource = buildDataSource(); FakeDataSource testDataSource = buildDataSource();
DefaultExtractorInput input = DefaultExtractorInput input =
new DefaultExtractorInput(testDataSource, 123, C.LENGTH_UNSET); new DefaultExtractorInput(testDataSource, 123, C.LENGTH_UNSET);
assertEquals(123, input.getPosition()); assertThat(input.getPosition()).isEqualTo(123);
} }
@Test
public void testRead() throws Exception { public void testRead() throws Exception {
DefaultExtractorInput input = createDefaultExtractorInput(); DefaultExtractorInput input = createDefaultExtractorInput();
byte[] target = new byte[TEST_DATA.length]; byte[] target = new byte[TEST_DATA.length];
// We expect to perform three reads of three bytes, as setup in buildTestDataSource. // We expect to perform three reads of three bytes, as setup in buildTestDataSource.
int bytesRead = 0; int bytesRead = 0;
bytesRead += input.read(target, 0, TEST_DATA.length); bytesRead += input.read(target, 0, TEST_DATA.length);
assertEquals(3, bytesRead); assertThat(bytesRead).isEqualTo(3);
bytesRead += input.read(target, 3, TEST_DATA.length); bytesRead += input.read(target, 3, TEST_DATA.length);
assertEquals(6, bytesRead); assertThat(bytesRead).isEqualTo(6);
bytesRead += input.read(target, 6, TEST_DATA.length); bytesRead += input.read(target, 6, TEST_DATA.length);
assertEquals(9, bytesRead); assertThat(bytesRead).isEqualTo(9);
// Check the read data is correct. // Check the read data is correct.
assertTrue(Arrays.equals(TEST_DATA, target)); assertThat(Arrays.equals(TEST_DATA, target)).isTrue();
// Check we're now indicated that the end of input is reached. // Check we're now indicated that the end of input is reached.
int expectedEndOfInput = input.read(target, 0, TEST_DATA.length); int expectedEndOfInput = input.read(target, 0, TEST_DATA.length);
assertEquals(C.RESULT_END_OF_INPUT, expectedEndOfInput); assertThat(expectedEndOfInput).isEqualTo(RESULT_END_OF_INPUT);
} }
@Test
public void testReadPeeked() throws Exception { public void testReadPeeked() throws Exception {
DefaultExtractorInput input = createDefaultExtractorInput(); DefaultExtractorInput input = createDefaultExtractorInput();
byte[] target = new byte[TEST_DATA.length]; byte[] target = new byte[TEST_DATA.length];
@ -65,12 +79,13 @@ public class DefaultExtractorInputTest extends TestCase {
input.advancePeekPosition(TEST_DATA.length); input.advancePeekPosition(TEST_DATA.length);
int bytesRead = input.read(target, 0, TEST_DATA.length); int bytesRead = input.read(target, 0, TEST_DATA.length);
assertEquals(TEST_DATA.length, bytesRead); assertThat(bytesRead).isEqualTo(TEST_DATA.length);
// Check the read data is correct. // Check the read data is correct.
assertTrue(Arrays.equals(TEST_DATA, target)); assertThat(Arrays.equals(TEST_DATA, target)).isTrue();
} }
@Test
public void testReadMoreDataPeeked() throws Exception { public void testReadMoreDataPeeked() throws Exception {
DefaultExtractorInput input = createDefaultExtractorInput(); DefaultExtractorInput input = createDefaultExtractorInput();
byte[] target = new byte[TEST_DATA.length]; byte[] target = new byte[TEST_DATA.length];
@ -78,22 +93,23 @@ public class DefaultExtractorInputTest extends TestCase {
input.advancePeekPosition(TEST_DATA.length); input.advancePeekPosition(TEST_DATA.length);
int bytesRead = input.read(target, 0, TEST_DATA.length + 1); int bytesRead = input.read(target, 0, TEST_DATA.length + 1);
assertEquals(TEST_DATA.length, bytesRead); assertThat(bytesRead).isEqualTo(TEST_DATA.length);
// Check the read data is correct. // Check the read data is correct.
assertTrue(Arrays.equals(TEST_DATA, target)); assertThat(Arrays.equals(TEST_DATA, target)).isTrue();
} }
@Test
public void testReadFullyOnce() throws Exception { public void testReadFullyOnce() throws Exception {
DefaultExtractorInput input = createDefaultExtractorInput(); DefaultExtractorInput input = createDefaultExtractorInput();
byte[] target = new byte[TEST_DATA.length]; byte[] target = new byte[TEST_DATA.length];
input.readFully(target, 0, TEST_DATA.length); input.readFully(target, 0, TEST_DATA.length);
// Check that we read the whole of TEST_DATA. // Check that we read the whole of TEST_DATA.
assertTrue(Arrays.equals(TEST_DATA, target)); assertThat(Arrays.equals(TEST_DATA, target)).isTrue();
assertEquals(TEST_DATA.length, input.getPosition()); assertThat(input.getPosition()).isEqualTo(TEST_DATA.length);
// Check that we see end of input if we read again with allowEndOfInput set. // Check that we see end of input if we read again with allowEndOfInput set.
boolean result = input.readFully(target, 0, 1, true); boolean result = input.readFully(target, 0, 1, true);
assertFalse(result); assertThat(result).isFalse();
// Check that we fail with EOFException we read again with allowEndOfInput unset. // Check that we fail with EOFException we read again with allowEndOfInput unset.
try { try {
input.readFully(target, 0, 1); input.readFully(target, 0, 1);
@ -103,19 +119,21 @@ public class DefaultExtractorInputTest extends TestCase {
} }
} }
@Test
public void testReadFullyTwice() throws Exception { public void testReadFullyTwice() throws Exception {
// Read TEST_DATA in two parts. // Read TEST_DATA in two parts.
DefaultExtractorInput input = createDefaultExtractorInput(); DefaultExtractorInput input = createDefaultExtractorInput();
byte[] target = new byte[5]; byte[] target = new byte[5];
input.readFully(target, 0, 5); input.readFully(target, 0, 5);
assertTrue(Arrays.equals(Arrays.copyOf(TEST_DATA, 5), target)); assertThat(Arrays.equals(copyOf(TEST_DATA, 5), target)).isTrue();
assertEquals(5, input.getPosition()); assertThat(input.getPosition()).isEqualTo(5);
target = new byte[4]; target = new byte[4];
input.readFully(target, 0, 4); input.readFully(target, 0, 4);
assertTrue(Arrays.equals(Arrays.copyOfRange(TEST_DATA, 5, 9), target)); assertThat(Arrays.equals(copyOfRange(TEST_DATA, 5, 9), target)).isTrue();
assertEquals(5 + 4, input.getPosition()); assertThat(input.getPosition()).isEqualTo(5 + 4);
} }
@Test
public void testReadFullyTooMuch() throws Exception { public void testReadFullyTooMuch() throws Exception {
// Read more than TEST_DATA. Should fail with an EOFException. Position should not update. // Read more than TEST_DATA. Should fail with an EOFException. Position should not update.
DefaultExtractorInput input = createDefaultExtractorInput(); DefaultExtractorInput input = createDefaultExtractorInput();
@ -126,7 +144,7 @@ public class DefaultExtractorInputTest extends TestCase {
} catch (EOFException e) { } catch (EOFException e) {
// Expected. // Expected.
} }
assertEquals(0, input.getPosition()); assertThat(input.getPosition()).isEqualTo(0);
// Read more than TEST_DATA with allowEndOfInput set. Should fail with an EOFException because // Read more than TEST_DATA with allowEndOfInput set. Should fail with an EOFException because
// the end of input isn't encountered immediately. Position should not update. // the end of input isn't encountered immediately. Position should not update.
@ -138,9 +156,10 @@ public class DefaultExtractorInputTest extends TestCase {
} catch (EOFException e) { } catch (EOFException e) {
// Expected. // Expected.
} }
assertEquals(0, input.getPosition()); assertThat(input.getPosition()).isEqualTo(0);
} }
@Test
public void testReadFullyWithFailingDataSource() throws Exception { public void testReadFullyWithFailingDataSource() throws Exception {
FakeDataSource testDataSource = buildFailingDataSource(); FakeDataSource testDataSource = buildFailingDataSource();
DefaultExtractorInput input = new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNSET); DefaultExtractorInput input = new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNSET);
@ -152,9 +171,10 @@ public class DefaultExtractorInputTest extends TestCase {
// Expected. // Expected.
} }
// The position should not have advanced. // The position should not have advanced.
assertEquals(0, input.getPosition()); assertThat(input.getPosition()).isEqualTo(0);
} }
@Test
public void testReadFullyHalfPeeked() throws Exception { public void testReadFullyHalfPeeked() throws Exception {
DefaultExtractorInput input = createDefaultExtractorInput(); DefaultExtractorInput input = createDefaultExtractorInput();
byte[] target = new byte[TEST_DATA.length]; byte[] target = new byte[TEST_DATA.length];
@ -164,22 +184,24 @@ public class DefaultExtractorInputTest extends TestCase {
input.readFully(target, 0, TEST_DATA.length); input.readFully(target, 0, TEST_DATA.length);
// Check the read data is correct. // Check the read data is correct.
assertTrue(Arrays.equals(TEST_DATA, target)); assertThat(Arrays.equals(TEST_DATA, target)).isTrue();
assertEquals(TEST_DATA.length, input.getPosition()); assertThat(input.getPosition()).isEqualTo(TEST_DATA.length);
} }
@Test
public void testSkip() throws Exception { public void testSkip() throws Exception {
FakeDataSource testDataSource = buildDataSource(); FakeDataSource testDataSource = buildDataSource();
DefaultExtractorInput input = new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNSET); DefaultExtractorInput input = new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNSET);
// We expect to perform three skips of three bytes, as setup in buildTestDataSource. // We expect to perform three skips of three bytes, as setup in buildTestDataSource.
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
assertEquals(3, input.skip(TEST_DATA.length)); assertThat(input.skip(TEST_DATA.length)).isEqualTo(3);
} }
// Check we're now indicated that the end of input is reached. // Check we're now indicated that the end of input is reached.
int expectedEndOfInput = input.skip(TEST_DATA.length); int expectedEndOfInput = input.skip(TEST_DATA.length);
assertEquals(C.RESULT_END_OF_INPUT, expectedEndOfInput); assertThat(expectedEndOfInput).isEqualTo(RESULT_END_OF_INPUT);
} }
@Test
public void testLargeSkip() throws Exception { public void testLargeSkip() throws Exception {
FakeDataSource testDataSource = buildLargeDataSource(); FakeDataSource testDataSource = buildLargeDataSource();
DefaultExtractorInput input = new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNSET); DefaultExtractorInput input = new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNSET);
@ -190,14 +212,15 @@ public class DefaultExtractorInputTest extends TestCase {
} }
} }
@Test
public void testSkipFullyOnce() throws Exception { public void testSkipFullyOnce() throws Exception {
// Skip TEST_DATA. // Skip TEST_DATA.
DefaultExtractorInput input = createDefaultExtractorInput(); DefaultExtractorInput input = createDefaultExtractorInput();
input.skipFully(TEST_DATA.length); input.skipFully(TEST_DATA.length);
assertEquals(TEST_DATA.length, input.getPosition()); assertThat(input.getPosition()).isEqualTo(TEST_DATA.length);
// Check that we see end of input if we skip again with allowEndOfInput set. // Check that we see end of input if we skip again with allowEndOfInput set.
boolean result = input.skipFully(1, true); boolean result = input.skipFully(1, true);
assertFalse(result); assertThat(result).isFalse();
// Check that we fail with EOFException we skip again. // Check that we fail with EOFException we skip again.
try { try {
input.skipFully(1); input.skipFully(1);
@ -207,15 +230,17 @@ public class DefaultExtractorInputTest extends TestCase {
} }
} }
@Test
public void testSkipFullyTwice() throws Exception { public void testSkipFullyTwice() throws Exception {
// Skip TEST_DATA in two parts. // Skip TEST_DATA in two parts.
DefaultExtractorInput input = createDefaultExtractorInput(); DefaultExtractorInput input = createDefaultExtractorInput();
input.skipFully(5); input.skipFully(5);
assertEquals(5, input.getPosition()); assertThat(input.getPosition()).isEqualTo(5);
input.skipFully(4); input.skipFully(4);
assertEquals(5 + 4, input.getPosition()); assertThat(input.getPosition()).isEqualTo(5 + 4);
} }
@Test
public void testSkipFullyTwicePeeked() throws Exception { public void testSkipFullyTwicePeeked() throws Exception {
// Skip TEST_DATA. // Skip TEST_DATA.
DefaultExtractorInput input = createDefaultExtractorInput(); DefaultExtractorInput input = createDefaultExtractorInput();
@ -224,12 +249,13 @@ public class DefaultExtractorInputTest extends TestCase {
int halfLength = TEST_DATA.length / 2; int halfLength = TEST_DATA.length / 2;
input.skipFully(halfLength); input.skipFully(halfLength);
assertEquals(halfLength, input.getPosition()); assertThat(input.getPosition()).isEqualTo(halfLength);
input.skipFully(TEST_DATA.length - halfLength); input.skipFully(TEST_DATA.length - halfLength);
assertEquals(TEST_DATA.length, input.getPosition()); assertThat(input.getPosition()).isEqualTo(TEST_DATA.length);
} }
@Test
public void testSkipFullyTooMuch() throws Exception { public void testSkipFullyTooMuch() throws Exception {
// Skip more than TEST_DATA. Should fail with an EOFException. Position should not update. // Skip more than TEST_DATA. Should fail with an EOFException. Position should not update.
DefaultExtractorInput input = createDefaultExtractorInput(); DefaultExtractorInput input = createDefaultExtractorInput();
@ -239,7 +265,7 @@ public class DefaultExtractorInputTest extends TestCase {
} catch (EOFException e) { } catch (EOFException e) {
// Expected. // Expected.
} }
assertEquals(0, input.getPosition()); assertThat(input.getPosition()).isEqualTo(0);
// Skip more than TEST_DATA with allowEndOfInput set. Should fail with an EOFException because // Skip more than TEST_DATA with allowEndOfInput set. Should fail with an EOFException because
// the end of input isn't encountered immediately. Position should not update. // the end of input isn't encountered immediately. Position should not update.
@ -250,9 +276,10 @@ public class DefaultExtractorInputTest extends TestCase {
} catch (EOFException e) { } catch (EOFException e) {
// Expected. // Expected.
} }
assertEquals(0, input.getPosition()); assertThat(input.getPosition()).isEqualTo(0);
} }
@Test
public void testSkipFullyWithFailingDataSource() throws Exception { public void testSkipFullyWithFailingDataSource() throws Exception {
FakeDataSource testDataSource = buildFailingDataSource(); FakeDataSource testDataSource = buildFailingDataSource();
DefaultExtractorInput input = new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNSET); DefaultExtractorInput input = new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNSET);
@ -263,9 +290,10 @@ public class DefaultExtractorInputTest extends TestCase {
// Expected. // Expected.
} }
// The position should not have advanced. // The position should not have advanced.
assertEquals(0, input.getPosition()); assertThat(input.getPosition()).isEqualTo(0);
} }
@Test
public void testSkipFullyLarge() throws Exception { public void testSkipFullyLarge() throws Exception {
// Tests skipping an amount of data that's larger than any internal scratch space. // Tests skipping an amount of data that's larger than any internal scratch space.
int largeSkipSize = 1024 * 1024; int largeSkipSize = 1024 * 1024;
@ -275,7 +303,7 @@ public class DefaultExtractorInputTest extends TestCase {
DefaultExtractorInput input = new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNSET); DefaultExtractorInput input = new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNSET);
input.skipFully(largeSkipSize); input.skipFully(largeSkipSize);
assertEquals(largeSkipSize, input.getPosition()); assertThat(input.getPosition()).isEqualTo(largeSkipSize);
// Check that we fail with EOFException we skip again. // Check that we fail with EOFException we skip again.
try { try {
input.skipFully(1); input.skipFully(1);
@ -285,22 +313,23 @@ public class DefaultExtractorInputTest extends TestCase {
} }
} }
@Test
public void testPeekFully() throws Exception { public void testPeekFully() throws Exception {
DefaultExtractorInput input = createDefaultExtractorInput(); DefaultExtractorInput input = createDefaultExtractorInput();
byte[] target = new byte[TEST_DATA.length]; byte[] target = new byte[TEST_DATA.length];
input.peekFully(target, 0, TEST_DATA.length); input.peekFully(target, 0, TEST_DATA.length);
// Check that we read the whole of TEST_DATA. // Check that we read the whole of TEST_DATA.
assertTrue(Arrays.equals(TEST_DATA, target)); assertThat(Arrays.equals(TEST_DATA, target)).isTrue();
assertEquals(0, input.getPosition()); assertThat(input.getPosition()).isEqualTo(0);
assertEquals(TEST_DATA.length, input.getPeekPosition()); assertThat(input.getPeekPosition()).isEqualTo(TEST_DATA.length);
// Check that we can read again from the buffer // Check that we can read again from the buffer
byte[] target2 = new byte[TEST_DATA.length]; byte[] target2 = new byte[TEST_DATA.length];
input.readFully(target2, 0, TEST_DATA.length); input.readFully(target2, 0, TEST_DATA.length);
assertTrue(Arrays.equals(TEST_DATA, target2)); assertThat(Arrays.equals(TEST_DATA, target2)).isTrue();
assertEquals(TEST_DATA.length, input.getPosition()); assertThat(input.getPosition()).isEqualTo(TEST_DATA.length);
assertEquals(TEST_DATA.length, input.getPeekPosition()); assertThat(input.getPeekPosition()).isEqualTo(TEST_DATA.length);
// Check that we fail with EOFException if we peek again // Check that we fail with EOFException if we peek again
try { try {
@ -311,20 +340,21 @@ public class DefaultExtractorInputTest extends TestCase {
} }
} }
@Test
public void testResetPeekPosition() throws Exception { public void testResetPeekPosition() throws Exception {
DefaultExtractorInput input = createDefaultExtractorInput(); DefaultExtractorInput input = createDefaultExtractorInput();
byte[] target = new byte[TEST_DATA.length]; byte[] target = new byte[TEST_DATA.length];
input.peekFully(target, 0, TEST_DATA.length); input.peekFully(target, 0, TEST_DATA.length);
// Check that we read the whole of TEST_DATA. // Check that we read the whole of TEST_DATA.
assertTrue(Arrays.equals(TEST_DATA, target)); assertThat(Arrays.equals(TEST_DATA, target)).isTrue();
assertEquals(0, input.getPosition()); assertThat(input.getPosition()).isEqualTo(0);
// Check that we can peek again after resetting. // Check that we can peek again after resetting.
input.resetPeekPosition(); input.resetPeekPosition();
byte[] target2 = new byte[TEST_DATA.length]; byte[] target2 = new byte[TEST_DATA.length];
input.peekFully(target2, 0, TEST_DATA.length); input.peekFully(target2, 0, TEST_DATA.length);
assertTrue(Arrays.equals(TEST_DATA, target2)); assertThat(Arrays.equals(TEST_DATA, target2)).isTrue();
// Check that we fail with EOFException if we peek past the end of the input. // Check that we fail with EOFException if we peek past the end of the input.
try { try {
@ -335,40 +365,43 @@ public class DefaultExtractorInputTest extends TestCase {
} }
} }
@Test
public void testPeekFullyAtEndOfStreamWithAllowEndOfInputSucceeds() throws Exception { public void testPeekFullyAtEndOfStreamWithAllowEndOfInputSucceeds() throws Exception {
DefaultExtractorInput input = createDefaultExtractorInput(); DefaultExtractorInput input = createDefaultExtractorInput();
byte[] target = new byte[TEST_DATA.length]; byte[] target = new byte[TEST_DATA.length];
// Check peeking up to the end of input succeeds. // Check peeking up to the end of input succeeds.
assertTrue(input.peekFully(target, 0, TEST_DATA.length, true)); assertThat(input.peekFully(target, 0, TEST_DATA.length, true)).isTrue();
// Check peeking at the end of input with allowEndOfInput signals the end of input. // Check peeking at the end of input with allowEndOfInput signals the end of input.
assertFalse(input.peekFully(target, 0, 1, true)); assertThat(input.peekFully(target, 0, 1, true)).isFalse();
} }
@Test
public void testPeekFullyAtEndThenReadEndOfInput() throws Exception { public void testPeekFullyAtEndThenReadEndOfInput() throws Exception {
DefaultExtractorInput input = createDefaultExtractorInput(); DefaultExtractorInput input = createDefaultExtractorInput();
byte[] target = new byte[TEST_DATA.length]; byte[] target = new byte[TEST_DATA.length];
// Peek up to the end of the input. // Peek up to the end of the input.
assertTrue(input.peekFully(target, 0, TEST_DATA.length, false)); assertThat(input.peekFully(target, 0, TEST_DATA.length, false)).isTrue();
// Peek the end of the input. // Peek the end of the input.
assertFalse(input.peekFully(target, 0, 1, true)); assertThat(input.peekFully(target, 0, 1, true)).isFalse();
// Read up to the end of the input. // Read up to the end of the input.
assertTrue(input.readFully(target, 0, TEST_DATA.length, false)); assertThat(input.readFully(target, 0, TEST_DATA.length, false)).isTrue();
// Read the end of the input. // Read the end of the input.
assertFalse(input.readFully(target, 0, 1, true)); assertThat(input.readFully(target, 0, 1, true)).isFalse();
} }
@Test
public void testPeekFullyAcrossEndOfInputWithAllowEndOfInputFails() throws Exception { public void testPeekFullyAcrossEndOfInputWithAllowEndOfInputFails() throws Exception {
DefaultExtractorInput input = createDefaultExtractorInput(); DefaultExtractorInput input = createDefaultExtractorInput();
byte[] target = new byte[TEST_DATA.length]; byte[] target = new byte[TEST_DATA.length];
// Check peeking before the end of input with allowEndOfInput succeeds. // Check peeking before the end of input with allowEndOfInput succeeds.
assertTrue(input.peekFully(target, 0, TEST_DATA.length - 1, true)); assertThat(input.peekFully(target, 0, TEST_DATA.length - 1, true)).isTrue();
// Check peeking across the end of input with allowEndOfInput throws. // Check peeking across the end of input with allowEndOfInput throws.
try { try {
@ -379,12 +412,13 @@ public class DefaultExtractorInputTest extends TestCase {
} }
} }
@Test
public void testResetAndPeekFullyPastEndOfStreamWithAllowEndOfInputFails() throws Exception { public void testResetAndPeekFullyPastEndOfStreamWithAllowEndOfInputFails() throws Exception {
DefaultExtractorInput input = createDefaultExtractorInput(); DefaultExtractorInput input = createDefaultExtractorInput();
byte[] target = new byte[TEST_DATA.length]; byte[] target = new byte[TEST_DATA.length];
// Check peeking up to the end of input succeeds. // Check peeking up to the end of input succeeds.
assertTrue(input.peekFully(target, 0, TEST_DATA.length, true)); assertThat(input.peekFully(target, 0, TEST_DATA.length, true)).isTrue();
input.resetPeekPosition(); input.resetPeekPosition();
try { try {
// Check peeking one more byte throws. // Check peeking one more byte throws.

View File

@ -15,20 +15,28 @@
*/ */
package com.google.android.exoplayer2.extractor; package com.google.android.exoplayer2.extractor;
import static com.google.common.truth.Truth.assertThat;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import junit.framework.TestCase; import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/** /**
* Unit test for {@link Extractor}. * Unit test for {@link Extractor}.
*/ */
public class ExtractorTest extends TestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class ExtractorTest {
public static void testConstants() { @Test
public void testConstants() {
// Sanity check that constant values match those defined by {@link C}. // Sanity check that constant values match those defined by {@link C}.
assertEquals(C.RESULT_END_OF_INPUT, Extractor.RESULT_END_OF_INPUT); assertThat(Extractor.RESULT_END_OF_INPUT).isEqualTo(C.RESULT_END_OF_INPUT);
// Sanity check that the other constant values don't overlap. // Sanity check that the other constant values don't overlap.
assertTrue(C.RESULT_END_OF_INPUT != Extractor.RESULT_CONTINUE); assertThat(C.RESULT_END_OF_INPUT != Extractor.RESULT_CONTINUE).isTrue();
assertTrue(C.RESULT_END_OF_INPUT != Extractor.RESULT_SEEK); assertThat(C.RESULT_END_OF_INPUT != Extractor.RESULT_SEEK).isTrue();
} }
} }

View File

@ -15,6 +15,8 @@
*/ */
package com.google.android.exoplayer2.extractor.mkv; package com.google.android.exoplayer2.extractor.mkv;
import static com.google.common.truth.Truth.assertThat;
import com.google.android.exoplayer2.extractor.ExtractorInput; import com.google.android.exoplayer2.extractor.ExtractorInput;
import com.google.android.exoplayer2.testutil.FakeExtractorInput; import com.google.android.exoplayer2.testutil.FakeExtractorInput;
import com.google.android.exoplayer2.testutil.TestUtil; import com.google.android.exoplayer2.testutil.TestUtil;
@ -22,13 +24,19 @@ import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import junit.framework.TestCase; import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/** /**
* Tests {@link DefaultEbmlReader}. * Tests {@link DefaultEbmlReader}.
*/ */
public class DefaultEbmlReaderTest extends TestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public class DefaultEbmlReaderTest {
@Test
public void testMasterElement() throws IOException, InterruptedException { public void testMasterElement() throws IOException, InterruptedException {
ExtractorInput input = createTestInput(0x1A, 0x45, 0xDF, 0xA3, 0x84, 0x42, 0x85, 0x81, 0x01); ExtractorInput input = createTestInput(0x1A, 0x45, 0xDF, 0xA3, 0x84, 0x42, 0x85, 0x81, 0x01);
TestOutput expected = new TestOutput(); TestOutput expected = new TestOutput();
@ -38,6 +46,7 @@ public class DefaultEbmlReaderTest extends TestCase {
assertEvents(input, expected.events); assertEvents(input, expected.events);
} }
@Test
public void testMasterElementEmpty() throws IOException, InterruptedException { public void testMasterElementEmpty() throws IOException, InterruptedException {
ExtractorInput input = createTestInput(0x18, 0x53, 0x80, 0x67, 0x80); ExtractorInput input = createTestInput(0x18, 0x53, 0x80, 0x67, 0x80);
TestOutput expected = new TestOutput(); TestOutput expected = new TestOutput();
@ -46,6 +55,7 @@ public class DefaultEbmlReaderTest extends TestCase {
assertEvents(input, expected.events); assertEvents(input, expected.events);
} }
@Test
public void testUnsignedIntegerElement() throws IOException, InterruptedException { public void testUnsignedIntegerElement() throws IOException, InterruptedException {
// 0xFE is chosen because for signed integers it should be interpreted as -2 // 0xFE is chosen because for signed integers it should be interpreted as -2
ExtractorInput input = createTestInput(0x42, 0xF7, 0x81, 0xFE); ExtractorInput input = createTestInput(0x42, 0xF7, 0x81, 0xFE);
@ -54,6 +64,7 @@ public class DefaultEbmlReaderTest extends TestCase {
assertEvents(input, expected.events); assertEvents(input, expected.events);
} }
@Test
public void testUnsignedIntegerElementLarge() throws IOException, InterruptedException { public void testUnsignedIntegerElementLarge() throws IOException, InterruptedException {
ExtractorInput input = ExtractorInput input =
createTestInput(0x42, 0xF7, 0x88, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF); createTestInput(0x42, 0xF7, 0x88, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
@ -62,6 +73,7 @@ public class DefaultEbmlReaderTest extends TestCase {
assertEvents(input, expected.events); assertEvents(input, expected.events);
} }
@Test
public void testUnsignedIntegerElementTooLargeBecomesNegative() public void testUnsignedIntegerElementTooLargeBecomesNegative()
throws IOException, InterruptedException { throws IOException, InterruptedException {
ExtractorInput input = ExtractorInput input =
@ -71,6 +83,7 @@ public class DefaultEbmlReaderTest extends TestCase {
assertEvents(input, expected.events); assertEvents(input, expected.events);
} }
@Test
public void testStringElement() throws IOException, InterruptedException { public void testStringElement() throws IOException, InterruptedException {
ExtractorInput input = createTestInput(0x42, 0x82, 0x86, 0x41, 0x62, 0x63, 0x31, 0x32, 0x33); ExtractorInput input = createTestInput(0x42, 0x82, 0x86, 0x41, 0x62, 0x63, 0x31, 0x32, 0x33);
TestOutput expected = new TestOutput(); TestOutput expected = new TestOutput();
@ -78,6 +91,7 @@ public class DefaultEbmlReaderTest extends TestCase {
assertEvents(input, expected.events); assertEvents(input, expected.events);
} }
@Test
public void testStringElementEmpty() throws IOException, InterruptedException { public void testStringElementEmpty() throws IOException, InterruptedException {
ExtractorInput input = createTestInput(0x42, 0x82, 0x80); ExtractorInput input = createTestInput(0x42, 0x82, 0x80);
TestOutput expected = new TestOutput(); TestOutput expected = new TestOutput();
@ -85,6 +99,7 @@ public class DefaultEbmlReaderTest extends TestCase {
assertEvents(input, expected.events); assertEvents(input, expected.events);
} }
@Test
public void testFloatElementFourBytes() throws IOException, InterruptedException { public void testFloatElementFourBytes() throws IOException, InterruptedException {
ExtractorInput input = ExtractorInput input =
createTestInput(0x44, 0x89, 0x84, 0x3F, 0x80, 0x00, 0x00); createTestInput(0x44, 0x89, 0x84, 0x3F, 0x80, 0x00, 0x00);
@ -93,6 +108,7 @@ public class DefaultEbmlReaderTest extends TestCase {
assertEvents(input, expected.events); assertEvents(input, expected.events);
} }
@Test
public void testFloatElementEightBytes() throws IOException, InterruptedException { public void testFloatElementEightBytes() throws IOException, InterruptedException {
ExtractorInput input = ExtractorInput input =
createTestInput(0x44, 0x89, 0x88, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); createTestInput(0x44, 0x89, 0x88, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
@ -101,6 +117,7 @@ public class DefaultEbmlReaderTest extends TestCase {
assertEvents(input, expected.events); assertEvents(input, expected.events);
} }
@Test
public void testBinaryElement() throws IOException, InterruptedException { public void testBinaryElement() throws IOException, InterruptedException {
ExtractorInput input = ExtractorInput input =
createTestInput(0xA3, 0x88, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08); createTestInput(0xA3, 0x88, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08);
@ -118,16 +135,16 @@ public class DefaultEbmlReaderTest extends TestCase {
// We expect the number of successful reads to equal the number of expected events. // We expect the number of successful reads to equal the number of expected events.
for (int i = 0; i < expectedEvents.size(); i++) { for (int i = 0; i < expectedEvents.size(); i++) {
assertTrue(reader.read(input)); assertThat(reader.read(input)).isTrue();
} }
// The next read should be unsuccessful. // The next read should be unsuccessful.
assertFalse(reader.read(input)); assertThat(reader.read(input)).isFalse();
// Check that we really did get to the end of input. // Check that we really did get to the end of input.
assertFalse(input.readFully(new byte[1], 0, 1, true)); assertThat(input.readFully(new byte[1], 0, 1, true)).isFalse();
assertEquals(expectedEvents.size(), output.events.size()); assertThat(output.events).hasSize(expectedEvents.size());
for (int i = 0; i < expectedEvents.size(); i++) { for (int i = 0; i < expectedEvents.size(); i++) {
assertEquals(expectedEvents.get(i), output.events.get(i)); assertThat(output.events.get(i)).isEqualTo(expectedEvents.get(i));
} }
} }

View File

@ -15,18 +15,28 @@
*/ */
package com.google.android.exoplayer2.extractor.mkv; package com.google.android.exoplayer2.extractor.mkv;
import static com.google.android.exoplayer2.C.RESULT_END_OF_INPUT;
import static com.google.android.exoplayer2.C.RESULT_MAX_LENGTH_EXCEEDED;
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.extractor.ExtractorInput; import com.google.android.exoplayer2.extractor.ExtractorInput;
import com.google.android.exoplayer2.testutil.FakeExtractorInput; import com.google.android.exoplayer2.testutil.FakeExtractorInput;
import com.google.android.exoplayer2.testutil.FakeExtractorInput.SimulatedIOException; import com.google.android.exoplayer2.testutil.FakeExtractorInput.SimulatedIOException;
import java.io.EOFException; import java.io.EOFException;
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;
/** /**
* Tests for {@link VarintReader}. * Tests for {@link VarintReader}.
*/ */
public final class VarintReaderTest extends TestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class VarintReaderTest {
private static final byte MAX_BYTE = (byte) 0xFF; private static final byte MAX_BYTE = (byte) 0xFF;
@ -78,6 +88,7 @@ public final class VarintReaderTest extends TestCase {
private static final long VALUE_8_BYTE_MAX = 0xFFFFFFFFFFFFFFL; private static final long VALUE_8_BYTE_MAX = 0xFFFFFFFFFFFFFFL;
private static final long VALUE_8_BYTE_MAX_WITH_MASK = 0x1FFFFFFFFFFFFFFL; private static final long VALUE_8_BYTE_MAX_WITH_MASK = 0x1FFFFFFFFFFFFFFL;
@Test
public void testReadVarintEndOfInputAtStart() throws IOException, InterruptedException { public void testReadVarintEndOfInputAtStart() throws IOException, InterruptedException {
VarintReader reader = new VarintReader(); VarintReader reader = new VarintReader();
// Build an input with no data. // Build an input with no data.
@ -86,7 +97,7 @@ public final class VarintReaderTest extends TestCase {
.build(); .build();
// End of input allowed. // End of input allowed.
long result = reader.readUnsignedVarint(input, true, false, 8); long result = reader.readUnsignedVarint(input, true, false, 8);
assertEquals(C.RESULT_END_OF_INPUT, result); assertThat(result).isEqualTo(RESULT_END_OF_INPUT);
// End of input not allowed. // End of input not allowed.
try { try {
reader.readUnsignedVarint(input, false, false, 8); reader.readUnsignedVarint(input, false, false, 8);
@ -96,6 +107,7 @@ public final class VarintReaderTest extends TestCase {
} }
} }
@Test
public void testReadVarintExceedsMaximumAllowedLength() throws IOException, InterruptedException { public void testReadVarintExceedsMaximumAllowedLength() throws IOException, InterruptedException {
VarintReader reader = new VarintReader(); VarintReader reader = new VarintReader();
ExtractorInput input = new FakeExtractorInput.Builder() ExtractorInput input = new FakeExtractorInput.Builder()
@ -103,9 +115,10 @@ public final class VarintReaderTest extends TestCase {
.setSimulateUnknownLength(true) .setSimulateUnknownLength(true)
.build(); .build();
long result = reader.readUnsignedVarint(input, false, true, 4); long result = reader.readUnsignedVarint(input, false, true, 4);
assertEquals(C.RESULT_MAX_LENGTH_EXCEEDED, result); assertThat(result).isEqualTo(RESULT_MAX_LENGTH_EXCEEDED);
} }
@Test
public void testReadVarint() throws IOException, InterruptedException { public void testReadVarint() throws IOException, InterruptedException {
VarintReader reader = new VarintReader(); VarintReader reader = new VarintReader();
testReadVarint(reader, true, DATA_1_BYTE_0, 1, 0); testReadVarint(reader, true, DATA_1_BYTE_0, 1, 0);
@ -142,6 +155,7 @@ public final class VarintReaderTest extends TestCase {
testReadVarint(reader, false, DATA_8_BYTE_MAX, 8, VALUE_8_BYTE_MAX_WITH_MASK); testReadVarint(reader, false, DATA_8_BYTE_MAX, 8, VALUE_8_BYTE_MAX_WITH_MASK);
} }
@Test
public void testReadVarintFlaky() throws IOException, InterruptedException { public void testReadVarintFlaky() throws IOException, InterruptedException {
VarintReader reader = new VarintReader(); VarintReader reader = new VarintReader();
testReadVarintFlaky(reader, true, DATA_1_BYTE_0, 1, 0); testReadVarintFlaky(reader, true, DATA_1_BYTE_0, 1, 0);
@ -185,8 +199,8 @@ public final class VarintReaderTest extends TestCase {
.setSimulateUnknownLength(true) .setSimulateUnknownLength(true)
.build(); .build();
long result = reader.readUnsignedVarint(input, false, removeMask, 8); long result = reader.readUnsignedVarint(input, false, removeMask, 8);
assertEquals(expectedLength, input.getPosition()); assertThat(input.getPosition()).isEqualTo(expectedLength);
assertEquals(expectedValue, result); assertThat(result).isEqualTo(expectedValue);
} }
private static void testReadVarintFlaky(VarintReader reader, boolean removeMask, byte[] data, private static void testReadVarintFlaky(VarintReader reader, boolean removeMask, byte[] data,
@ -209,8 +223,8 @@ public final class VarintReaderTest extends TestCase {
// Expected. // Expected.
} }
} }
assertEquals(expectedLength, input.getPosition()); assertThat(input.getPosition()).isEqualTo(expectedLength);
assertEquals(expectedValue, result); assertThat(result).isEqualTo(expectedValue);
} }
} }

View File

@ -15,16 +15,24 @@
*/ */
package com.google.android.exoplayer2.extractor.mp3; package com.google.android.exoplayer2.extractor.mp3;
import android.test.InstrumentationTestCase; 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.extractor.MpegAudioHeader; import com.google.android.exoplayer2.extractor.MpegAudioHeader;
import com.google.android.exoplayer2.util.ParsableByteArray; import com.google.android.exoplayer2.util.ParsableByteArray;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/** /**
* Tests for {@link XingSeeker}. * Tests for {@link XingSeeker}.
*/ */
public final class XingSeekerTest extends InstrumentationTestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class XingSeekerTest {
// Xing header/payload from http://storage.googleapis.com/exoplayer-test-media-0/play.mp3. // Xing header/payload from http://storage.googleapis.com/exoplayer-test-media-0/play.mp3.
private static final int XING_FRAME_HEADER_DATA = 0xFFFB3000; private static final int XING_FRAME_HEADER_DATA = 0xFFFB3000;
@ -51,7 +59,7 @@ public final class XingSeekerTest extends InstrumentationTestCase {
private XingSeeker seekerWithInputLength; private XingSeeker seekerWithInputLength;
private int xingFrameSize; private int xingFrameSize;
@Override @Before
public void setUp() throws Exception { public void setUp() throws Exception {
MpegAudioHeader xingFrameHeader = new MpegAudioHeader(); MpegAudioHeader xingFrameHeader = new MpegAudioHeader();
MpegAudioHeader.populateHeader(XING_FRAME_HEADER_DATA, xingFrameHeader); MpegAudioHeader.populateHeader(XING_FRAME_HEADER_DATA, xingFrameHeader);
@ -62,42 +70,49 @@ public final class XingSeekerTest extends InstrumentationTestCase {
xingFrameSize = xingFrameHeader.frameSize; xingFrameSize = xingFrameHeader.frameSize;
} }
@Test
public void testGetTimeUsBeforeFirstAudioFrame() { public void testGetTimeUsBeforeFirstAudioFrame() {
assertEquals(0, seeker.getTimeUs(-1)); assertThat(seeker.getTimeUs(-1)).isEqualTo(0);
assertEquals(0, seekerWithInputLength.getTimeUs(-1)); assertThat(seekerWithInputLength.getTimeUs(-1)).isEqualTo(0);
} }
@Test
public void testGetTimeUsAtFirstAudioFrame() { public void testGetTimeUsAtFirstAudioFrame() {
assertEquals(0, seeker.getTimeUs(XING_FRAME_POSITION + xingFrameSize)); assertThat(seeker.getTimeUs(XING_FRAME_POSITION + xingFrameSize)).isEqualTo(0);
assertEquals(0, seekerWithInputLength.getTimeUs(XING_FRAME_POSITION + xingFrameSize)); assertThat(seekerWithInputLength.getTimeUs(XING_FRAME_POSITION + xingFrameSize)).isEqualTo(0);
} }
@Test
public void testGetTimeUsAtEndOfStream() { public void testGetTimeUsAtEndOfStream() {
assertEquals(STREAM_DURATION_US, assertThat(seeker.getTimeUs(XING_FRAME_POSITION + xingFrameSize + STREAM_SIZE_BYTES))
seeker.getTimeUs(XING_FRAME_POSITION + xingFrameSize + STREAM_SIZE_BYTES)); .isEqualTo(STREAM_DURATION_US);
assertEquals(STREAM_DURATION_US, assertThat(
seekerWithInputLength.getTimeUs(XING_FRAME_POSITION + xingFrameSize + STREAM_SIZE_BYTES)); seekerWithInputLength.getTimeUs(XING_FRAME_POSITION + xingFrameSize + STREAM_SIZE_BYTES))
.isEqualTo(STREAM_DURATION_US);
} }
@Test
public void testGetPositionAtStartOfStream() { public void testGetPositionAtStartOfStream() {
assertEquals(XING_FRAME_POSITION + xingFrameSize, seeker.getPosition(0)); assertThat(seeker.getPosition(0)).isEqualTo(XING_FRAME_POSITION + xingFrameSize);
assertEquals(XING_FRAME_POSITION + xingFrameSize, seekerWithInputLength.getPosition(0)); assertThat(seekerWithInputLength.getPosition(0)).isEqualTo(XING_FRAME_POSITION + xingFrameSize);
} }
@Test
public void testGetPositionAtEndOfStream() { public void testGetPositionAtEndOfStream() {
assertEquals(XING_FRAME_POSITION + STREAM_SIZE_BYTES - 1, assertThat(seeker.getPosition(STREAM_DURATION_US))
seeker.getPosition(STREAM_DURATION_US)); .isEqualTo(XING_FRAME_POSITION + STREAM_SIZE_BYTES - 1);
assertEquals(XING_FRAME_POSITION + STREAM_SIZE_BYTES - 1, assertThat(seekerWithInputLength.getPosition(STREAM_DURATION_US))
seekerWithInputLength.getPosition(STREAM_DURATION_US)); .isEqualTo(XING_FRAME_POSITION + STREAM_SIZE_BYTES - 1);
} }
@Test
public void testGetTimeForAllPositions() { public void testGetTimeForAllPositions() {
for (int offset = xingFrameSize; offset < STREAM_SIZE_BYTES; offset++) { for (int offset = xingFrameSize; offset < STREAM_SIZE_BYTES; offset++) {
int position = XING_FRAME_POSITION + offset; int position = XING_FRAME_POSITION + offset;
long timeUs = seeker.getTimeUs(position); long timeUs = seeker.getTimeUs(position);
assertEquals(position, seeker.getPosition(timeUs)); assertThat(seeker.getPosition(timeUs)).isEqualTo(position);
timeUs = seekerWithInputLength.getTimeUs(position); timeUs = seekerWithInputLength.getTimeUs(position);
assertEquals(position, seekerWithInputLength.getPosition(timeUs)); assertThat(seekerWithInputLength.getPosition(timeUs)).isEqualTo(position);
} }
} }

View File

@ -15,14 +15,21 @@
*/ */
package com.google.android.exoplayer2.extractor.mp4; package com.google.android.exoplayer2.extractor.mp4;
import static com.google.common.truth.Truth.assertThat;
import com.google.android.exoplayer2.util.ParsableByteArray; import com.google.android.exoplayer2.util.ParsableByteArray;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import junit.framework.TestCase; import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/** /**
* Tests for {@link AtomParsers}. * Tests for {@link AtomParsers}.
*/ */
public final class AtomParsersTest extends TestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class AtomParsersTest {
private static final String ATOM_HEADER = "000000000000000000000000"; private static final String ATOM_HEADER = "000000000000000000000000";
private static final String SAMPLE_COUNT = "00000004"; private static final String SAMPLE_COUNT = "00000004";
@ -33,24 +40,27 @@ public final class AtomParsersTest extends TestCase {
private static final byte[] SIXTEEN_BIT_STZ2 = Util.getBytesFromHexString(ATOM_HEADER + "00000010" private static final byte[] SIXTEEN_BIT_STZ2 = Util.getBytesFromHexString(ATOM_HEADER + "00000010"
+ SAMPLE_COUNT + "0001000200030004"); + SAMPLE_COUNT + "0001000200030004");
@Test
public void testStz2Parsing4BitFieldSize() { public void testStz2Parsing4BitFieldSize() {
verifyParsing(new Atom.LeafAtom(Atom.TYPE_stsz, new ParsableByteArray(FOUR_BIT_STZ2))); verifyParsing(new Atom.LeafAtom(Atom.TYPE_stsz, new ParsableByteArray(FOUR_BIT_STZ2)));
} }
@Test
public void testStz2Parsing8BitFieldSize() { public void testStz2Parsing8BitFieldSize() {
verifyParsing(new Atom.LeafAtom(Atom.TYPE_stsz, new ParsableByteArray(EIGHT_BIT_STZ2))); verifyParsing(new Atom.LeafAtom(Atom.TYPE_stsz, new ParsableByteArray(EIGHT_BIT_STZ2)));
} }
@Test
public void testStz2Parsing16BitFieldSize() { public void testStz2Parsing16BitFieldSize() {
verifyParsing(new Atom.LeafAtom(Atom.TYPE_stsz, new ParsableByteArray(SIXTEEN_BIT_STZ2))); verifyParsing(new Atom.LeafAtom(Atom.TYPE_stsz, new ParsableByteArray(SIXTEEN_BIT_STZ2)));
} }
private void verifyParsing(Atom.LeafAtom stz2Atom) { private void verifyParsing(Atom.LeafAtom stz2Atom) {
AtomParsers.Stz2SampleSizeBox box = new AtomParsers.Stz2SampleSizeBox(stz2Atom); AtomParsers.Stz2SampleSizeBox box = new AtomParsers.Stz2SampleSizeBox(stz2Atom);
assertEquals(4, box.getSampleCount()); assertThat(box.getSampleCount()).isEqualTo(4);
assertFalse(box.isFixedSampleSize()); assertThat(box.isFixedSampleSize()).isFalse();
for (int i = 0; i < box.getSampleCount(); i++) { for (int i = 0; i < box.getSampleCount(); i++) {
assertEquals(i + 1, box.readNextSampleSize()); assertThat(box.readNextSampleSize()).isEqualTo(i + 1);
} }
} }

View File

@ -15,33 +15,44 @@
*/ */
package com.google.android.exoplayer2.extractor.mp4; package com.google.android.exoplayer2.extractor.mp4;
import android.test.MoreAsserts; import static com.google.android.exoplayer2.C.WIDEVINE_UUID;
import static com.google.android.exoplayer2.extractor.mp4.Atom.TYPE_pssh;
import static com.google.android.exoplayer2.extractor.mp4.Atom.parseFullAtomFlags;
import static com.google.android.exoplayer2.extractor.mp4.Atom.parseFullAtomVersion;
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.util.ParsableByteArray; import com.google.android.exoplayer2.util.ParsableByteArray;
import java.util.UUID; import java.util.UUID;
import junit.framework.TestCase; import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/** /**
* Tests for {@link PsshAtomUtil}. * Tests for {@link PsshAtomUtil}.
*/ */
public class PsshAtomUtilTest extends TestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class PsshAtomUtilTest {
@Test
public void testBuildPsshAtom() { public void testBuildPsshAtom() {
byte[] schemeData = new byte[]{0, 1, 2, 3, 4, 5}; byte[] schemeData = new byte[]{0, 1, 2, 3, 4, 5};
byte[] psshAtom = PsshAtomUtil.buildPsshAtom(C.WIDEVINE_UUID, schemeData); byte[] psshAtom = PsshAtomUtil.buildPsshAtom(C.WIDEVINE_UUID, schemeData);
// Read the PSSH atom back and assert its content is as expected. // Read the PSSH atom back and assert its content is as expected.
ParsableByteArray parsablePsshAtom = new ParsableByteArray(psshAtom); ParsableByteArray parsablePsshAtom = new ParsableByteArray(psshAtom);
assertEquals(psshAtom.length, parsablePsshAtom.readUnsignedIntToInt()); // length assertThat(parsablePsshAtom.readUnsignedIntToInt()).isEqualTo(psshAtom.length); // length
assertEquals(Atom.TYPE_pssh, parsablePsshAtom.readInt()); // type assertThat(parsablePsshAtom.readInt()).isEqualTo(TYPE_pssh); // type
int fullAtomInt = parsablePsshAtom.readInt(); // version + flags int fullAtomInt = parsablePsshAtom.readInt(); // version + flags
assertEquals(0, Atom.parseFullAtomVersion(fullAtomInt)); assertThat(parseFullAtomVersion(fullAtomInt)).isEqualTo(0);
assertEquals(0, Atom.parseFullAtomFlags(fullAtomInt)); assertThat(parseFullAtomFlags(fullAtomInt)).isEqualTo(0);
UUID systemId = new UUID(parsablePsshAtom.readLong(), parsablePsshAtom.readLong()); UUID systemId = new UUID(parsablePsshAtom.readLong(), parsablePsshAtom.readLong());
assertEquals(C.WIDEVINE_UUID, systemId); assertThat(systemId).isEqualTo(WIDEVINE_UUID);
assertEquals(schemeData.length, parsablePsshAtom.readUnsignedIntToInt()); assertThat(parsablePsshAtom.readUnsignedIntToInt()).isEqualTo(schemeData.length);
byte[] psshSchemeData = new byte[schemeData.length]; byte[] psshSchemeData = new byte[schemeData.length];
parsablePsshAtom.readBytes(psshSchemeData, 0, schemeData.length); parsablePsshAtom.readBytes(psshSchemeData, 0, schemeData.length);
MoreAsserts.assertEquals(schemeData, psshSchemeData); assertThat(psshSchemeData).isEqualTo(schemeData);
} }
} }

View File

@ -15,54 +15,67 @@
*/ */
package com.google.android.exoplayer2.extractor.ogg; package com.google.android.exoplayer2.extractor.ogg;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import com.google.android.exoplayer2.extractor.ExtractorInput; import com.google.android.exoplayer2.extractor.ExtractorInput;
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.TestUtil; import com.google.android.exoplayer2.testutil.TestUtil;
import java.io.EOFException; import java.io.EOFException;
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;
import org.robolectric.annotation.Config;
/** /**
* Unit test for {@link DefaultOggSeeker} utility methods. * Unit test for {@link DefaultOggSeeker} utility methods.
*/ */
public class DefaultOggSeekerUtilMethodsTest extends TestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class DefaultOggSeekerUtilMethodsTest {
private final Random random = new Random(0); private final Random random = new Random(0);
@Test
public void testSkipToNextPage() throws Exception { public void testSkipToNextPage() throws Exception {
FakeExtractorInput extractorInput = TestData.createInput( FakeExtractorInput extractorInput = OggTestData.createInput(
TestUtil.joinByteArrays( TestUtil.joinByteArrays(
TestUtil.buildTestData(4000, random), TestUtil.buildTestData(4000, random),
new byte[] {'O', 'g', 'g', 'S'}, new byte[] {'O', 'g', 'g', 'S'},
TestUtil.buildTestData(4000, random) TestUtil.buildTestData(4000, random)
), false); ), false);
skipToNextPage(extractorInput); skipToNextPage(extractorInput);
assertEquals(4000, extractorInput.getPosition()); assertThat(extractorInput.getPosition()).isEqualTo(4000);
} }
@Test
public void testSkipToNextPageOverlap() throws Exception { public void testSkipToNextPageOverlap() throws Exception {
FakeExtractorInput extractorInput = TestData.createInput( FakeExtractorInput extractorInput = OggTestData.createInput(
TestUtil.joinByteArrays( TestUtil.joinByteArrays(
TestUtil.buildTestData(2046, random), TestUtil.buildTestData(2046, random),
new byte[] {'O', 'g', 'g', 'S'}, new byte[] {'O', 'g', 'g', 'S'},
TestUtil.buildTestData(4000, random) TestUtil.buildTestData(4000, random)
), false); ), false);
skipToNextPage(extractorInput); skipToNextPage(extractorInput);
assertEquals(2046, extractorInput.getPosition()); assertThat(extractorInput.getPosition()).isEqualTo(2046);
} }
@Test
public void testSkipToNextPageInputShorterThanPeekLength() throws Exception { public void testSkipToNextPageInputShorterThanPeekLength() throws Exception {
FakeExtractorInput extractorInput = TestData.createInput( FakeExtractorInput extractorInput = OggTestData.createInput(
TestUtil.joinByteArrays( TestUtil.joinByteArrays(
new byte[] {'x', 'O', 'g', 'g', 'S'} new byte[] {'x', 'O', 'g', 'g', 'S'}
), false); ), false);
skipToNextPage(extractorInput); skipToNextPage(extractorInput);
assertEquals(1, extractorInput.getPosition()); assertThat(extractorInput.getPosition()).isEqualTo(1);
} }
@Test
public void testSkipToNextPageNoMatch() throws Exception { public void testSkipToNextPageNoMatch() throws Exception {
FakeExtractorInput extractorInput = TestData.createInput( FakeExtractorInput extractorInput = OggTestData.createInput(
new byte[] {'g', 'g', 'S', 'O', 'g', 'g'}, false); new byte[] {'g', 'g', 'S', 'O', 'g', 'g'}, false);
try { try {
skipToNextPage(extractorInput); skipToNextPage(extractorInput);
@ -84,16 +97,17 @@ public class DefaultOggSeekerUtilMethodsTest extends TestCase {
} }
} }
@Test
public void testSkipToPageOfGranule() throws IOException, InterruptedException { public void testSkipToPageOfGranule() throws IOException, InterruptedException {
byte[] packet = TestUtil.buildTestData(3 * 254, random); byte[] packet = TestUtil.buildTestData(3 * 254, random);
byte[] data = TestUtil.joinByteArrays( byte[] data = TestUtil.joinByteArrays(
TestData.buildOggHeader(0x01, 20000, 1000, 0x03), OggTestData.buildOggHeader(0x01, 20000, 1000, 0x03),
TestUtil.createByteArray(254, 254, 254), // Laces. TestUtil.createByteArray(254, 254, 254), // Laces.
packet, packet,
TestData.buildOggHeader(0x04, 40000, 1001, 0x03), OggTestData.buildOggHeader(0x04, 40000, 1001, 0x03),
TestUtil.createByteArray(254, 254, 254), // Laces. TestUtil.createByteArray(254, 254, 254), // Laces.
packet, packet,
TestData.buildOggHeader(0x04, 60000, 1002, 0x03), OggTestData.buildOggHeader(0x04, 60000, 1002, 0x03),
TestUtil.createByteArray(254, 254, 254), // Laces. TestUtil.createByteArray(254, 254, 254), // Laces.
packet); packet);
FakeExtractorInput input = new FakeExtractorInput.Builder().setData(data).build(); FakeExtractorInput input = new FakeExtractorInput.Builder().setData(data).build();
@ -101,44 +115,46 @@ public class DefaultOggSeekerUtilMethodsTest extends TestCase {
// expect to be granule of the previous page returned as elapsedSamples // expect to be granule of the previous page returned as elapsedSamples
skipToPageOfGranule(input, 54000, 40000); skipToPageOfGranule(input, 54000, 40000);
// expect to be at the start of the third page // expect to be at the start of the third page
assertEquals(2 * (30 + (3 * 254)), input.getPosition()); assertThat(input.getPosition()).isEqualTo(2 * (30 + (3 * 254)));
} }
@Test
public void testSkipToPageOfGranulePreciseMatch() throws IOException, InterruptedException { public void testSkipToPageOfGranulePreciseMatch() throws IOException, InterruptedException {
byte[] packet = TestUtil.buildTestData(3 * 254, random); byte[] packet = TestUtil.buildTestData(3 * 254, random);
byte[] data = TestUtil.joinByteArrays( byte[] data = TestUtil.joinByteArrays(
TestData.buildOggHeader(0x01, 20000, 1000, 0x03), OggTestData.buildOggHeader(0x01, 20000, 1000, 0x03),
TestUtil.createByteArray(254, 254, 254), // Laces. TestUtil.createByteArray(254, 254, 254), // Laces.
packet, packet,
TestData.buildOggHeader(0x04, 40000, 1001, 0x03), OggTestData.buildOggHeader(0x04, 40000, 1001, 0x03),
TestUtil.createByteArray(254, 254, 254), // Laces. TestUtil.createByteArray(254, 254, 254), // Laces.
packet, packet,
TestData.buildOggHeader(0x04, 60000, 1002, 0x03), OggTestData.buildOggHeader(0x04, 60000, 1002, 0x03),
TestUtil.createByteArray(254, 254, 254), // Laces. TestUtil.createByteArray(254, 254, 254), // Laces.
packet); packet);
FakeExtractorInput input = new FakeExtractorInput.Builder().setData(data).build(); FakeExtractorInput input = new FakeExtractorInput.Builder().setData(data).build();
skipToPageOfGranule(input, 40000, 20000); skipToPageOfGranule(input, 40000, 20000);
// expect to be at the start of the second page // expect to be at the start of the second page
assertEquals((30 + (3 * 254)), input.getPosition()); assertThat(input.getPosition()).isEqualTo(30 + (3 * 254));
} }
@Test
public void testSkipToPageOfGranuleAfterTargetPage() throws IOException, InterruptedException { public void testSkipToPageOfGranuleAfterTargetPage() throws IOException, InterruptedException {
byte[] packet = TestUtil.buildTestData(3 * 254, random); byte[] packet = TestUtil.buildTestData(3 * 254, random);
byte[] data = TestUtil.joinByteArrays( byte[] data = TestUtil.joinByteArrays(
TestData.buildOggHeader(0x01, 20000, 1000, 0x03), OggTestData.buildOggHeader(0x01, 20000, 1000, 0x03),
TestUtil.createByteArray(254, 254, 254), // Laces. TestUtil.createByteArray(254, 254, 254), // Laces.
packet, packet,
TestData.buildOggHeader(0x04, 40000, 1001, 0x03), OggTestData.buildOggHeader(0x04, 40000, 1001, 0x03),
TestUtil.createByteArray(254, 254, 254), // Laces. TestUtil.createByteArray(254, 254, 254), // Laces.
packet, packet,
TestData.buildOggHeader(0x04, 60000, 1002, 0x03), OggTestData.buildOggHeader(0x04, 60000, 1002, 0x03),
TestUtil.createByteArray(254, 254, 254), // Laces. TestUtil.createByteArray(254, 254, 254), // Laces.
packet); packet);
FakeExtractorInput input = new FakeExtractorInput.Builder().setData(data).build(); FakeExtractorInput input = new FakeExtractorInput.Builder().setData(data).build();
skipToPageOfGranule(input, 10000, -1); skipToPageOfGranule(input, 10000, -1);
assertEquals(0, input.getPosition()); assertThat(input.getPosition()).isEqualTo(0);
} }
private void skipToPageOfGranule(ExtractorInput input, long granule, private void skipToPageOfGranule(ExtractorInput input, long granule,
@ -146,7 +162,8 @@ public class DefaultOggSeekerUtilMethodsTest extends TestCase {
DefaultOggSeeker oggSeeker = new DefaultOggSeeker(0, input.getLength(), new FlacReader(), 1, 2); DefaultOggSeeker oggSeeker = new DefaultOggSeeker(0, input.getLength(), new FlacReader(), 1, 2);
while (true) { while (true) {
try { try {
assertEquals(elapsedSamplesExpected, oggSeeker.skipToPageOfGranule(input, granule, -1)); assertThat(oggSeeker.skipToPageOfGranule(input, granule, -1))
.isEqualTo(elapsedSamplesExpected);
return; return;
} catch (FakeExtractorInput.SimulatedIOException e) { } catch (FakeExtractorInput.SimulatedIOException e) {
input.resetPeekPosition(); input.resetPeekPosition();
@ -154,24 +171,26 @@ public class DefaultOggSeekerUtilMethodsTest extends TestCase {
} }
} }
@Test
public void testReadGranuleOfLastPage() throws IOException, InterruptedException { public void testReadGranuleOfLastPage() throws IOException, InterruptedException {
FakeExtractorInput input = TestData.createInput(TestUtil.joinByteArrays( FakeExtractorInput input = OggTestData.createInput(TestUtil.joinByteArrays(
TestUtil.buildTestData(100, random), TestUtil.buildTestData(100, random),
TestData.buildOggHeader(0x00, 20000, 66, 3), OggTestData.buildOggHeader(0x00, 20000, 66, 3),
TestUtil.createByteArray(254, 254, 254), // laces TestUtil.createByteArray(254, 254, 254), // laces
TestUtil.buildTestData(3 * 254, random), TestUtil.buildTestData(3 * 254, random),
TestData.buildOggHeader(0x00, 40000, 67, 3), OggTestData.buildOggHeader(0x00, 40000, 67, 3),
TestUtil.createByteArray(254, 254, 254), // laces TestUtil.createByteArray(254, 254, 254), // laces
TestUtil.buildTestData(3 * 254, random), TestUtil.buildTestData(3 * 254, random),
TestData.buildOggHeader(0x05, 60000, 68, 3), OggTestData.buildOggHeader(0x05, 60000, 68, 3),
TestUtil.createByteArray(254, 254, 254), // laces TestUtil.createByteArray(254, 254, 254), // laces
TestUtil.buildTestData(3 * 254, random) TestUtil.buildTestData(3 * 254, random)
), false); ), false);
assertReadGranuleOfLastPage(input, 60000); assertReadGranuleOfLastPage(input, 60000);
} }
@Test
public void testReadGranuleOfLastPageAfterLastHeader() throws IOException, InterruptedException { public void testReadGranuleOfLastPageAfterLastHeader() throws IOException, InterruptedException {
FakeExtractorInput input = TestData.createInput(TestUtil.buildTestData(100, random), false); FakeExtractorInput input = OggTestData.createInput(TestUtil.buildTestData(100, random), false);
try { try {
assertReadGranuleOfLastPage(input, 60000); assertReadGranuleOfLastPage(input, 60000);
fail(); fail();
@ -180,9 +199,10 @@ public class DefaultOggSeekerUtilMethodsTest extends TestCase {
} }
} }
@Test
public void testReadGranuleOfLastPageWithUnboundedLength() public void testReadGranuleOfLastPageWithUnboundedLength()
throws IOException, InterruptedException { throws IOException, InterruptedException {
FakeExtractorInput input = TestData.createInput(new byte[0], true); FakeExtractorInput input = OggTestData.createInput(new byte[0], true);
try { try {
assertReadGranuleOfLastPage(input, 60000); assertReadGranuleOfLastPage(input, 60000);
fail(); fail();
@ -196,7 +216,7 @@ public class DefaultOggSeekerUtilMethodsTest extends TestCase {
DefaultOggSeeker oggSeeker = new DefaultOggSeeker(0, input.getLength(), new FlacReader(), 1, 2); DefaultOggSeeker oggSeeker = new DefaultOggSeeker(0, input.getLength(), new FlacReader(), 1, 2);
while (true) { while (true) {
try { try {
assertEquals(expected, oggSeeker.readGranuleOfLastPage(input)); assertThat(oggSeeker.readGranuleOfLastPage(input)).isEqualTo(expected);
break; break;
} catch (FakeExtractorInput.SimulatedIOException e) { } catch (FakeExtractorInput.SimulatedIOException e) {
// ignored // ignored

View File

@ -15,67 +15,79 @@
*/ */
package com.google.android.exoplayer2.extractor.ogg; package com.google.android.exoplayer2.extractor.ogg;
import static com.google.common.truth.Truth.assertThat;
import com.google.android.exoplayer2.testutil.FakeExtractorInput; import com.google.android.exoplayer2.testutil.FakeExtractorInput;
import com.google.android.exoplayer2.testutil.FakeExtractorInput.SimulatedIOException; import com.google.android.exoplayer2.testutil.FakeExtractorInput.SimulatedIOException;
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 junit.framework.TestCase; import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/** /**
* Unit test for {@link OggPageHeader}. * Unit test for {@link OggPageHeader}.
*/ */
public final class OggPageHeaderTest extends TestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class OggPageHeaderTest {
@Test
public void testPopulatePageHeader() throws IOException, InterruptedException { public void testPopulatePageHeader() throws IOException, InterruptedException {
FakeExtractorInput input = TestData.createInput(TestUtil.joinByteArrays( FakeExtractorInput input = OggTestData.createInput(TestUtil.joinByteArrays(
TestData.buildOggHeader(0x01, 123456, 4, 2), OggTestData.buildOggHeader(0x01, 123456, 4, 2),
TestUtil.createByteArray(2, 2) TestUtil.createByteArray(2, 2)
), true); ), true);
OggPageHeader header = new OggPageHeader(); OggPageHeader header = new OggPageHeader();
populatePageHeader(input, header, false); populatePageHeader(input, header, false);
assertEquals(0x01, header.type); assertThat(header.type).isEqualTo(0x01);
assertEquals(27 + 2, header.headerSize); assertThat(header.headerSize).isEqualTo(27 + 2);
assertEquals(4, header.bodySize); assertThat(header.bodySize).isEqualTo(4);
assertEquals(2, header.pageSegmentCount); assertThat(header.pageSegmentCount).isEqualTo(2);
assertEquals(123456, header.granulePosition); assertThat(header.granulePosition).isEqualTo(123456);
assertEquals(4, header.pageSequenceNumber); assertThat(header.pageSequenceNumber).isEqualTo(4);
assertEquals(0x1000, header.streamSerialNumber); assertThat(header.streamSerialNumber).isEqualTo(0x1000);
assertEquals(0x100000, header.pageChecksum); assertThat(header.pageChecksum).isEqualTo(0x100000);
assertEquals(0, header.revision); assertThat(header.revision).isEqualTo(0);
} }
@Test
public void testPopulatePageHeaderQuiteOnExceptionLessThan27Bytes() public void testPopulatePageHeaderQuiteOnExceptionLessThan27Bytes()
throws IOException, InterruptedException { throws IOException, InterruptedException {
FakeExtractorInput input = TestData.createInput(TestUtil.createByteArray(2, 2), false); FakeExtractorInput input = OggTestData.createInput(TestUtil.createByteArray(2, 2), false);
OggPageHeader header = new OggPageHeader(); OggPageHeader header = new OggPageHeader();
assertFalse(populatePageHeader(input, header, true)); assertThat(populatePageHeader(input, header, true)).isFalse();
} }
@Test
public void testPopulatePageHeaderQuiteOnExceptionNotOgg() public void testPopulatePageHeaderQuiteOnExceptionNotOgg()
throws IOException, InterruptedException { throws IOException, InterruptedException {
byte[] headerBytes = TestUtil.joinByteArrays( byte[] headerBytes = TestUtil.joinByteArrays(
TestData.buildOggHeader(0x01, 123456, 4, 2), OggTestData.buildOggHeader(0x01, 123456, 4, 2),
TestUtil.createByteArray(2, 2) TestUtil.createByteArray(2, 2)
); );
// change from 'O' to 'o' // change from 'O' to 'o'
headerBytes[0] = 'o'; headerBytes[0] = 'o';
FakeExtractorInput input = TestData.createInput(headerBytes, false); FakeExtractorInput input = OggTestData.createInput(headerBytes, false);
OggPageHeader header = new OggPageHeader(); OggPageHeader header = new OggPageHeader();
assertFalse(populatePageHeader(input, header, true)); assertThat(populatePageHeader(input, header, true)).isFalse();
} }
@Test
public void testPopulatePageHeaderQuiteOnExceptionWrongRevision() public void testPopulatePageHeaderQuiteOnExceptionWrongRevision()
throws IOException, InterruptedException { throws IOException, InterruptedException {
byte[] headerBytes = TestUtil.joinByteArrays( byte[] headerBytes = TestUtil.joinByteArrays(
TestData.buildOggHeader(0x01, 123456, 4, 2), OggTestData.buildOggHeader(0x01, 123456, 4, 2),
TestUtil.createByteArray(2, 2) TestUtil.createByteArray(2, 2)
); );
// change revision from 0 to 1 // change revision from 0 to 1
headerBytes[4] = 0x01; headerBytes[4] = 0x01;
FakeExtractorInput input = TestData.createInput(headerBytes, false); FakeExtractorInput input = OggTestData.createInput(headerBytes, false);
OggPageHeader header = new OggPageHeader(); OggPageHeader header = new OggPageHeader();
assertFalse(populatePageHeader(input, header, true)); assertThat(populatePageHeader(input, header, true)).isFalse();
} }
private boolean populatePageHeader(FakeExtractorInput input, OggPageHeader header, private boolean populatePageHeader(FakeExtractorInput input, OggPageHeader header,

View File

@ -0,0 +1,155 @@
/*
* 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.
*/
package com.google.android.exoplayer2.extractor.ogg;
import static com.google.common.truth.Truth.assertThat;
import com.google.android.exoplayer2.testutil.TestUtil;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit test for {@link VorbisBitArray}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class VorbisBitArrayTest {
@Test
public void testReadBit() {
VorbisBitArray bitArray = new VorbisBitArray(TestUtil.createByteArray(0x5c, 0x50));
assertThat(bitArray.readBit()).isFalse();
assertThat(bitArray.readBit()).isFalse();
assertThat(bitArray.readBit()).isTrue();
assertThat(bitArray.readBit()).isTrue();
assertThat(bitArray.readBit()).isTrue();
assertThat(bitArray.readBit()).isFalse();
assertThat(bitArray.readBit()).isTrue();
assertThat(bitArray.readBit()).isFalse();
assertThat(bitArray.readBit()).isFalse();
assertThat(bitArray.readBit()).isFalse();
assertThat(bitArray.readBit()).isFalse();
assertThat(bitArray.readBit()).isFalse();
assertThat(bitArray.readBit()).isTrue();
assertThat(bitArray.readBit()).isFalse();
assertThat(bitArray.readBit()).isTrue();
assertThat(bitArray.readBit()).isFalse();
}
@Test
public void testSkipBits() {
VorbisBitArray bitArray = new VorbisBitArray(TestUtil.createByteArray(0xF0, 0x0F));
bitArray.skipBits(10);
assertThat(bitArray.getPosition()).isEqualTo(10);
assertThat(bitArray.readBit()).isTrue();
assertThat(bitArray.readBit()).isTrue();
assertThat(bitArray.readBit()).isFalse();
bitArray.skipBits(1);
assertThat(bitArray.getPosition()).isEqualTo(14);
assertThat(bitArray.readBit()).isFalse();
assertThat(bitArray.readBit()).isFalse();
}
@Test
public void testGetPosition() throws Exception {
VorbisBitArray bitArray = new VorbisBitArray(TestUtil.createByteArray(0xF0, 0x0F));
assertThat(bitArray.getPosition()).isEqualTo(0);
bitArray.readBit();
assertThat(bitArray.getPosition()).isEqualTo(1);
bitArray.readBit();
bitArray.readBit();
bitArray.skipBits(4);
assertThat(bitArray.getPosition()).isEqualTo(7);
}
@Test
public void testSetPosition() throws Exception {
VorbisBitArray bitArray = new VorbisBitArray(TestUtil.createByteArray(0xF0, 0x0F));
assertThat(bitArray.getPosition()).isEqualTo(0);
bitArray.setPosition(4);
assertThat(bitArray.getPosition()).isEqualTo(4);
bitArray.setPosition(15);
assertThat(bitArray.readBit()).isFalse();
}
@Test
public void testReadInt32() {
VorbisBitArray bitArray = new VorbisBitArray(TestUtil.createByteArray(0xF0, 0x0F, 0xF0, 0x0F));
assertThat(bitArray.readBits(32)).isEqualTo(0x0FF00FF0);
bitArray = new VorbisBitArray(TestUtil.createByteArray(0x0F, 0xF0, 0x0F, 0xF0));
assertThat(bitArray.readBits(32)).isEqualTo(0xF00FF00F);
}
@Test
public void testReadBits() throws Exception {
VorbisBitArray bitArray = new VorbisBitArray(TestUtil.createByteArray(0x03, 0x22));
assertThat(bitArray.readBits(2)).isEqualTo(3);
bitArray.skipBits(6);
assertThat(bitArray.readBits(2)).isEqualTo(2);
bitArray.skipBits(2);
assertThat(bitArray.readBits(2)).isEqualTo(2);
bitArray.reset();
assertThat(bitArray.readBits(16)).isEqualTo(0x2203);
}
@Test
public void testRead4BitsBeyondBoundary() throws Exception {
VorbisBitArray bitArray = new VorbisBitArray(TestUtil.createByteArray(0x2e, 0x10));
assertThat(bitArray.readBits(7)).isEqualTo(0x2e);
assertThat(bitArray.getPosition()).isEqualTo(7);
assertThat(bitArray.readBits(4)).isEqualTo(0x0);
}
@Test
public void testReadBitsBeyondByteBoundaries() throws Exception {
VorbisBitArray bitArray = new VorbisBitArray(TestUtil.createByteArray(0xFF, 0x0F, 0xFF, 0x0F));
assertThat(bitArray.readBits(32)).isEqualTo(0x0FFF0FFF);
bitArray.reset();
bitArray.skipBits(4);
assertThat(bitArray.readBits(16)).isEqualTo(0xF0FF);
bitArray.reset();
bitArray.skipBits(6);
assertThat(bitArray.readBits(12)).isEqualTo(0xc3F);
bitArray.reset();
bitArray.skipBits(6);
assertThat(bitArray.readBit()).isTrue();
assertThat(bitArray.readBit()).isTrue();
assertThat(bitArray.bitsLeft()).isEqualTo(24);
bitArray.reset();
bitArray.skipBits(10);
assertThat(bitArray.readBits(5)).isEqualTo(3);
assertThat(bitArray.getPosition()).isEqualTo(15);
}
@Test
public void testReadBitsIllegalLengths() throws Exception {
VorbisBitArray bitArray = new VorbisBitArray(TestUtil.createByteArray(0x03, 0x22, 0x30));
// reading zero bits gets 0 without advancing position
// (like a zero-bit read is defined to yield zer0)
assertThat(bitArray.readBits(0)).isEqualTo(0);
assertThat(bitArray.getPosition()).isEqualTo(0);
bitArray.readBit();
assertThat(bitArray.getPosition()).isEqualTo(1);
}
}

View File

@ -0,0 +1,117 @@
/*
* 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.
*/
package com.google.android.exoplayer2.extractor.ogg;
import static com.google.android.exoplayer2.extractor.ogg.VorbisReader.readBits;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import com.google.android.exoplayer2.extractor.ExtractorInput;
import com.google.android.exoplayer2.extractor.ogg.VorbisReader.VorbisSetup;
import com.google.android.exoplayer2.testutil.FakeExtractorInput;
import com.google.android.exoplayer2.testutil.FakeExtractorInput.SimulatedIOException;
import com.google.android.exoplayer2.testutil.OggTestData;
import com.google.android.exoplayer2.util.ParsableByteArray;
import java.io.IOException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit test for {@link VorbisReader}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class VorbisReaderTest {
@Test
public void testReadBits() throws Exception {
assertThat(readBits((byte) 0x00, 2, 2)).isEqualTo(0);
assertThat(readBits((byte) 0x02, 1, 1)).isEqualTo(1);
assertThat(readBits((byte) 0xF0, 4, 4)).isEqualTo(15);
assertThat(readBits((byte) 0x80, 1, 7)).isEqualTo(1);
}
@Test
public void testAppendNumberOfSamples() throws Exception {
ParsableByteArray buffer = new ParsableByteArray(4);
buffer.setLimit(0);
VorbisReader.appendNumberOfSamples(buffer, 0x01234567);
assertThat(buffer.limit()).isEqualTo(4);
assertThat(buffer.data[0]).isEqualTo(0x67);
assertThat(buffer.data[1]).isEqualTo(0x45);
assertThat(buffer.data[2]).isEqualTo(0x23);
assertThat(buffer.data[3]).isEqualTo(0x01);
}
@Test
public void testReadSetupHeadersWithIOExceptions() throws IOException, InterruptedException {
byte[] data = OggTestData.getVorbisHeaderPages();
ExtractorInput input = new FakeExtractorInput.Builder().setData(data).setSimulateIOErrors(true)
.setSimulateUnknownLength(true).setSimulatePartialReads(true).build();
VorbisReader reader = new VorbisReader();
VorbisReader.VorbisSetup vorbisSetup = readSetupHeaders(reader, input);
assertThat(vorbisSetup.idHeader).isNotNull();
assertThat(vorbisSetup.commentHeader).isNotNull();
assertThat(vorbisSetup.setupHeaderData).isNotNull();
assertThat(vorbisSetup.modes).isNotNull();
assertThat(vorbisSetup.commentHeader.length).isEqualTo(45);
assertThat(vorbisSetup.idHeader.data).hasLength(30);
assertThat(vorbisSetup.setupHeaderData).hasLength(3597);
assertThat(vorbisSetup.idHeader.bitrateMax).isEqualTo(-1);
assertThat(vorbisSetup.idHeader.bitrateMin).isEqualTo(-1);
assertThat(vorbisSetup.idHeader.bitrateNominal).isEqualTo(66666);
assertThat(vorbisSetup.idHeader.blockSize0).isEqualTo(512);
assertThat(vorbisSetup.idHeader.blockSize1).isEqualTo(1024);
assertThat(vorbisSetup.idHeader.channels).isEqualTo(2);
assertThat(vorbisSetup.idHeader.framingFlag).isTrue();
assertThat(vorbisSetup.idHeader.sampleRate).isEqualTo(22050);
assertThat(vorbisSetup.idHeader.version).isEqualTo(0);
assertThat(vorbisSetup.commentHeader.vendor).isEqualTo("Xiph.Org libVorbis I 20030909");
assertThat(vorbisSetup.iLogModes).isEqualTo(1);
assertThat(vorbisSetup.setupHeaderData[vorbisSetup.setupHeaderData.length - 1])
.isEqualTo(data[data.length - 1]);
assertThat(vorbisSetup.modes[0].blockFlag).isFalse();
assertThat(vorbisSetup.modes[1].blockFlag).isTrue();
}
private static VorbisSetup readSetupHeaders(VorbisReader reader, ExtractorInput input)
throws IOException, InterruptedException {
OggPacket oggPacket = new OggPacket();
while (true) {
try {
if (!oggPacket.populate(input)) {
fail();
}
VorbisSetup vorbisSetup = reader.readSetupHeaders(oggPacket.getPayload());
if (vorbisSetup != null) {
return vorbisSetup;
}
} catch (SimulatedIOException e) {
// Ignore.
}
}
}
}

View File

@ -0,0 +1,146 @@
/*
* 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.
*/
package com.google.android.exoplayer2.extractor.ogg;
import static com.google.android.exoplayer2.extractor.ogg.VorbisUtil.iLog;
import static com.google.android.exoplayer2.extractor.ogg.VorbisUtil.verifyVorbisHeaderCapturePattern;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.testutil.OggTestData;
import com.google.android.exoplayer2.util.ParsableByteArray;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit test for {@link VorbisUtil}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class VorbisUtilTest {
@Test
public void testILog() throws Exception {
assertThat(iLog(0)).isEqualTo(0);
assertThat(iLog(1)).isEqualTo(1);
assertThat(iLog(2)).isEqualTo(2);
assertThat(iLog(3)).isEqualTo(2);
assertThat(iLog(4)).isEqualTo(3);
assertThat(iLog(5)).isEqualTo(3);
assertThat(iLog(8)).isEqualTo(4);
assertThat(iLog(-1)).isEqualTo(0);
assertThat(iLog(-122)).isEqualTo(0);
}
@Test
public void testReadIdHeader() throws Exception {
byte[] data = OggTestData.getIdentificationHeaderData();
ParsableByteArray headerData = new ParsableByteArray(data, data.length);
VorbisUtil.VorbisIdHeader vorbisIdHeader =
VorbisUtil.readVorbisIdentificationHeader(headerData);
assertThat(vorbisIdHeader.sampleRate).isEqualTo(22050);
assertThat(vorbisIdHeader.version).isEqualTo(0);
assertThat(vorbisIdHeader.framingFlag).isTrue();
assertThat(vorbisIdHeader.channels).isEqualTo(2);
assertThat(vorbisIdHeader.blockSize0).isEqualTo(512);
assertThat(vorbisIdHeader.blockSize1).isEqualTo(1024);
assertThat(vorbisIdHeader.bitrateMax).isEqualTo(-1);
assertThat(vorbisIdHeader.bitrateMin).isEqualTo(-1);
assertThat(vorbisIdHeader.bitrateNominal).isEqualTo(66666);
assertThat(vorbisIdHeader.getApproximateBitrate()).isEqualTo(66666);
}
@Test
public void testReadCommentHeader() throws ParserException {
byte[] data = OggTestData.getCommentHeaderDataUTF8();
ParsableByteArray headerData = new ParsableByteArray(data, data.length);
VorbisUtil.CommentHeader commentHeader = VorbisUtil.readVorbisCommentHeader(headerData);
assertThat(commentHeader.vendor).isEqualTo("Xiph.Org libVorbis I 20120203 (Omnipresent)");
assertThat(commentHeader.comments).hasLength(3);
assertThat(commentHeader.comments[0]).isEqualTo("ALBUM=äö");
assertThat(commentHeader.comments[1]).isEqualTo("TITLE=A sample song");
assertThat(commentHeader.comments[2]).isEqualTo("ARTIST=Google");
}
@Test
public void testReadVorbisModes() throws ParserException {
byte[] data = OggTestData.getSetupHeaderData();
ParsableByteArray headerData = new ParsableByteArray(data, data.length);
VorbisUtil.Mode[] modes = VorbisUtil.readVorbisModes(headerData, 2);
assertThat(modes).hasLength(2);
assertThat(modes[0].blockFlag).isFalse();
assertThat(modes[0].mapping).isEqualTo(0);
assertThat(modes[0].transformType).isEqualTo(0);
assertThat(modes[0].windowType).isEqualTo(0);
assertThat(modes[1].blockFlag).isTrue();
assertThat(modes[1].mapping).isEqualTo(1);
assertThat(modes[1].transformType).isEqualTo(0);
assertThat(modes[1].windowType).isEqualTo(0);
}
@Test
public void testVerifyVorbisHeaderCapturePattern() throws ParserException {
ParsableByteArray header = new ParsableByteArray(
new byte[] {0x01, 'v', 'o', 'r', 'b', 'i', 's'});
assertThat(verifyVorbisHeaderCapturePattern(0x01, header, false)).isTrue();
}
@Test
public void testVerifyVorbisHeaderCapturePatternInvalidHeader() {
ParsableByteArray header = new ParsableByteArray(
new byte[] {0x01, 'v', 'o', 'r', 'b', 'i', 's'});
try {
VorbisUtil.verifyVorbisHeaderCapturePattern(0x99, header, false);
fail();
} catch (ParserException e) {
assertThat(e.getMessage()).isEqualTo("expected header type 99");
}
}
@Test
public void testVerifyVorbisHeaderCapturePatternInvalidHeaderQuite() throws ParserException {
ParsableByteArray header = new ParsableByteArray(
new byte[] {0x01, 'v', 'o', 'r', 'b', 'i', 's'});
assertThat(verifyVorbisHeaderCapturePattern(0x99, header, true)).isFalse();
}
@Test
public void testVerifyVorbisHeaderCapturePatternInvalidPattern() {
ParsableByteArray header = new ParsableByteArray(
new byte[] {0x01, 'x', 'v', 'o', 'r', 'b', 'i', 's'});
try {
VorbisUtil.verifyVorbisHeaderCapturePattern(0x01, header, false);
fail();
} catch (ParserException e) {
assertThat(e.getMessage()).isEqualTo("expected characters 'vorbis'");
}
}
@Test
public void testVerifyVorbisHeaderCapturePatternQuiteInvalidPatternQuite()
throws ParserException {
ParsableByteArray header = new ParsableByteArray(
new byte[] {0x01, 'x', 'v', 'o', 'r', 'b', 'i', 's'});
assertThat(verifyVorbisHeaderCapturePattern(0x01, header, true)).isFalse();
}
}

View File

@ -15,26 +15,35 @@
*/ */
package com.google.android.exoplayer2.extractor.ts; package com.google.android.exoplayer2.extractor.ts;
import static com.google.common.truth.Truth.assertThat;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import com.google.android.exoplayer2.extractor.ExtractorOutput; import com.google.android.exoplayer2.extractor.ExtractorOutput;
import com.google.android.exoplayer2.testutil.FakeExtractorOutput; import com.google.android.exoplayer2.testutil.FakeExtractorOutput;
import com.google.android.exoplayer2.util.ParsableByteArray; import com.google.android.exoplayer2.util.ParsableByteArray;
import com.google.android.exoplayer2.util.TimestampAdjuster; import com.google.android.exoplayer2.util.TimestampAdjuster;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.List; import java.util.List;
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;
/** /**
* Test for {@link SectionReader}. * Test for {@link SectionReader}.
*/ */
public class SectionReaderTest extends TestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class SectionReaderTest {
private byte[] packetPayload; private byte[] packetPayload;
private CustomSectionPayloadReader payloadReader; private CustomSectionPayloadReader payloadReader;
private SectionReader reader; private SectionReader reader;
@Override @Before
public void setUp() { public void setUp() {
packetPayload = new byte[512]; packetPayload = new byte[512];
Arrays.fill(packetPayload, (byte) 0xFF); Arrays.fill(packetPayload, (byte) 0xFF);
@ -44,27 +53,30 @@ public class SectionReaderTest extends TestCase {
new TsPayloadReader.TrackIdGenerator(0, 1)); new TsPayloadReader.TrackIdGenerator(0, 1));
} }
@Test
public void testSingleOnePacketSection() { public void testSingleOnePacketSection() {
packetPayload[0] = 3; packetPayload[0] = 3;
insertTableSection(4, (byte) 99, 3); insertTableSection(4, (byte) 99, 3);
reader.consume(new ParsableByteArray(packetPayload), true); reader.consume(new ParsableByteArray(packetPayload), true);
assertEquals(Collections.singletonList(99), payloadReader.parsedTableIds); assertThat(payloadReader.parsedTableIds).isEqualTo(singletonList(99));
} }
@Test
public void testHeaderSplitAcrossPackets() { public void testHeaderSplitAcrossPackets() {
packetPayload[0] = 3; // The first packet includes a pointer_field. packetPayload[0] = 3; // The first packet includes a pointer_field.
insertTableSection(4, (byte) 100, 3); // This section header spreads across both packets. insertTableSection(4, (byte) 100, 3); // This section header spreads across both packets.
ParsableByteArray firstPacket = new ParsableByteArray(packetPayload, 5); ParsableByteArray firstPacket = new ParsableByteArray(packetPayload, 5);
reader.consume(firstPacket, true); reader.consume(firstPacket, true);
assertEquals(Collections.emptyList(), payloadReader.parsedTableIds); assertThat(payloadReader.parsedTableIds).isEmpty();
ParsableByteArray secondPacket = new ParsableByteArray(packetPayload); ParsableByteArray secondPacket = new ParsableByteArray(packetPayload);
secondPacket.setPosition(5); secondPacket.setPosition(5);
reader.consume(secondPacket, false); reader.consume(secondPacket, false);
assertEquals(Collections.singletonList(100), payloadReader.parsedTableIds); assertThat(payloadReader.parsedTableIds).isEqualTo(singletonList(100));
} }
@Test
public void testFiveSectionsInTwoPackets() { public void testFiveSectionsInTwoPackets() {
packetPayload[0] = 0; // The first packet includes a pointer_field. packetPayload[0] = 0; // The first packet includes a pointer_field.
insertTableSection(1, (byte) 101, 10); insertTableSection(1, (byte) 101, 10);
@ -76,14 +88,15 @@ public class SectionReaderTest extends TestCase {
ParsableByteArray firstPacket = new ParsableByteArray(packetPayload, 40); ParsableByteArray firstPacket = new ParsableByteArray(packetPayload, 40);
reader.consume(firstPacket, true); reader.consume(firstPacket, true);
assertEquals(Arrays.asList(101, 102, 103), payloadReader.parsedTableIds); assertThat(payloadReader.parsedTableIds).isEqualTo(asList(101, 102, 103));
ParsableByteArray secondPacket = new ParsableByteArray(packetPayload); ParsableByteArray secondPacket = new ParsableByteArray(packetPayload);
secondPacket.setPosition(40); secondPacket.setPosition(40);
reader.consume(secondPacket, true); reader.consume(secondPacket, true);
assertEquals(Arrays.asList(101, 102, 103, 104, 105), payloadReader.parsedTableIds); assertThat(payloadReader.parsedTableIds).isEqualTo(asList(101, 102, 103, 104, 105));
} }
@Test
public void testLongSectionAcrossFourPackets() { public void testLongSectionAcrossFourPackets() {
packetPayload[0] = 13; // The first packet includes a pointer_field. packetPayload[0] = 13; // The first packet includes a pointer_field.
insertTableSection(1, (byte) 106, 10); // First section. Should be skipped. insertTableSection(1, (byte) 106, 10); // First section. Should be skipped.
@ -95,24 +108,25 @@ public class SectionReaderTest extends TestCase {
ParsableByteArray firstPacket = new ParsableByteArray(packetPayload, 100); ParsableByteArray firstPacket = new ParsableByteArray(packetPayload, 100);
reader.consume(firstPacket, true); reader.consume(firstPacket, true);
assertEquals(Collections.emptyList(), payloadReader.parsedTableIds); assertThat(payloadReader.parsedTableIds).isEmpty();
ParsableByteArray secondPacket = new ParsableByteArray(packetPayload, 200); ParsableByteArray secondPacket = new ParsableByteArray(packetPayload, 200);
secondPacket.setPosition(100); secondPacket.setPosition(100);
reader.consume(secondPacket, false); reader.consume(secondPacket, false);
assertEquals(Collections.emptyList(), payloadReader.parsedTableIds); assertThat(payloadReader.parsedTableIds).isEmpty();
ParsableByteArray thirdPacket = new ParsableByteArray(packetPayload, 300); ParsableByteArray thirdPacket = new ParsableByteArray(packetPayload, 300);
thirdPacket.setPosition(200); thirdPacket.setPosition(200);
reader.consume(thirdPacket, false); reader.consume(thirdPacket, false);
assertEquals(Collections.emptyList(), payloadReader.parsedTableIds); assertThat(payloadReader.parsedTableIds).isEmpty();
ParsableByteArray fourthPacket = new ParsableByteArray(packetPayload); ParsableByteArray fourthPacket = new ParsableByteArray(packetPayload);
fourthPacket.setPosition(300); fourthPacket.setPosition(300);
reader.consume(fourthPacket, true); reader.consume(fourthPacket, true);
assertEquals(Arrays.asList(107, 108), payloadReader.parsedTableIds); assertThat(payloadReader.parsedTableIds).isEqualTo(asList(107, 108));
} }
@Test
public void testSeek() { public void testSeek() {
packetPayload[0] = 13; // The first packet includes a pointer_field. packetPayload[0] = 13; // The first packet includes a pointer_field.
insertTableSection(1, (byte) 109, 10); // First section. Should be skipped. insertTableSection(1, (byte) 109, 10); // First section. Should be skipped.
@ -124,26 +138,27 @@ public class SectionReaderTest extends TestCase {
ParsableByteArray firstPacket = new ParsableByteArray(packetPayload, 100); ParsableByteArray firstPacket = new ParsableByteArray(packetPayload, 100);
reader.consume(firstPacket, true); reader.consume(firstPacket, true);
assertEquals(Collections.emptyList(), payloadReader.parsedTableIds); assertThat(payloadReader.parsedTableIds).isEmpty();
ParsableByteArray secondPacket = new ParsableByteArray(packetPayload, 200); ParsableByteArray secondPacket = new ParsableByteArray(packetPayload, 200);
secondPacket.setPosition(100); secondPacket.setPosition(100);
reader.consume(secondPacket, false); reader.consume(secondPacket, false);
assertEquals(Collections.emptyList(), payloadReader.parsedTableIds); assertThat(payloadReader.parsedTableIds).isEmpty();
ParsableByteArray thirdPacket = new ParsableByteArray(packetPayload, 300); ParsableByteArray thirdPacket = new ParsableByteArray(packetPayload, 300);
thirdPacket.setPosition(200); thirdPacket.setPosition(200);
reader.consume(thirdPacket, false); reader.consume(thirdPacket, false);
assertEquals(Collections.emptyList(), payloadReader.parsedTableIds); assertThat(payloadReader.parsedTableIds).isEmpty();
reader.seek(); reader.seek();
ParsableByteArray fourthPacket = new ParsableByteArray(packetPayload); ParsableByteArray fourthPacket = new ParsableByteArray(packetPayload);
fourthPacket.setPosition(300); fourthPacket.setPosition(300);
reader.consume(fourthPacket, true); reader.consume(fourthPacket, true);
assertEquals(Collections.singletonList(111), payloadReader.parsedTableIds); assertThat(payloadReader.parsedTableIds).isEqualTo(singletonList(111));
} }
@Test
public void testCrcChecks() { public void testCrcChecks() {
byte[] correctCrcPat = new byte[] { byte[] correctCrcPat = new byte[] {
(byte) 0x0, (byte) 0x0, (byte) 0xb0, (byte) 0xd, (byte) 0x0, (byte) 0x1, (byte) 0xc1, (byte) 0x0, (byte) 0x0, (byte) 0xb0, (byte) 0xd, (byte) 0x0, (byte) 0x1, (byte) 0xc1,
@ -153,9 +168,9 @@ public class SectionReaderTest extends TestCase {
// Crc field is incorrect, and should not be passed to the payload reader. // Crc field is incorrect, and should not be passed to the payload reader.
incorrectCrcPat[16]--; incorrectCrcPat[16]--;
reader.consume(new ParsableByteArray(correctCrcPat), true); reader.consume(new ParsableByteArray(correctCrcPat), true);
assertEquals(Collections.singletonList(0), payloadReader.parsedTableIds); assertThat(payloadReader.parsedTableIds).isEqualTo(singletonList(0));
reader.consume(new ParsableByteArray(incorrectCrcPat), true); reader.consume(new ParsableByteArray(incorrectCrcPat), true);
assertEquals(Collections.singletonList(0), payloadReader.parsedTableIds); assertThat(payloadReader.parsedTableIds).isEqualTo(singletonList(0));
} }
// Internal methods. // Internal methods.

View File

@ -15,17 +15,24 @@
*/ */
package com.google.android.exoplayer2.metadata.emsg; package com.google.android.exoplayer2.metadata.emsg;
import android.test.MoreAsserts; import static com.google.common.truth.Truth.assertThat;
import com.google.android.exoplayer2.metadata.Metadata; import com.google.android.exoplayer2.metadata.Metadata;
import com.google.android.exoplayer2.metadata.MetadataInputBuffer; import com.google.android.exoplayer2.metadata.MetadataInputBuffer;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import junit.framework.TestCase; import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/** /**
* Test for {@link EventMessageDecoder}. * Test for {@link EventMessageDecoder}.
*/ */
public final class EventMessageDecoderTest extends TestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class EventMessageDecoderTest {
@Test
public void testDecodeEventMessage() { public void testDecodeEventMessage() {
byte[] rawEmsgBody = new byte[] { byte[] rawEmsgBody = new byte[] {
117, 114, 110, 58, 116, 101, 115, 116, 0, // scheme_id_uri = "urn:test" 117, 114, 110, 58, 116, 101, 115, 116, 0, // scheme_id_uri = "urn:test"
@ -39,13 +46,13 @@ public final class EventMessageDecoderTest extends TestCase {
MetadataInputBuffer buffer = new MetadataInputBuffer(); MetadataInputBuffer buffer = new MetadataInputBuffer();
buffer.data = ByteBuffer.allocate(rawEmsgBody.length).put(rawEmsgBody); buffer.data = ByteBuffer.allocate(rawEmsgBody.length).put(rawEmsgBody);
Metadata metadata = decoder.decode(buffer); Metadata metadata = decoder.decode(buffer);
assertEquals(1, metadata.length()); assertThat(metadata.length()).isEqualTo(1);
EventMessage eventMessage = (EventMessage) metadata.get(0); EventMessage eventMessage = (EventMessage) metadata.get(0);
assertEquals("urn:test", eventMessage.schemeIdUri); assertThat(eventMessage.schemeIdUri).isEqualTo("urn:test");
assertEquals("123", eventMessage.value); assertThat(eventMessage.value).isEqualTo("123");
assertEquals(3000, eventMessage.durationMs); assertThat(eventMessage.durationMs).isEqualTo(3000);
assertEquals(1000403, eventMessage.id); assertThat(eventMessage.id).isEqualTo(1000403);
MoreAsserts.assertEquals(new byte[] {0, 1, 2, 3, 4}, eventMessage.messageData); assertThat(eventMessage.messageData).isEqualTo(new byte[]{0, 1, 2, 3, 4});
} }
} }

View File

@ -15,14 +15,22 @@
*/ */
package com.google.android.exoplayer2.metadata.emsg; package com.google.android.exoplayer2.metadata.emsg;
import static com.google.common.truth.Truth.assertThat;
import android.os.Parcel; import android.os.Parcel;
import junit.framework.TestCase; import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/** /**
* Test for {@link EventMessage}. * Test for {@link EventMessage}.
*/ */
public final class EventMessageTest extends TestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class EventMessageTest {
@Test
public void testEventMessageParcelable() { public void testEventMessageParcelable() {
EventMessage eventMessage = new EventMessage("urn:test", "123", 3000, 1000403, EventMessage eventMessage = new EventMessage("urn:test", "123", 3000, 1000403,
new byte[] {0, 1, 2, 3, 4}); new byte[] {0, 1, 2, 3, 4});
@ -33,7 +41,7 @@ public final class EventMessageTest extends TestCase {
parcel.setDataPosition(0); parcel.setDataPosition(0);
EventMessage fromParcelEventMessage = EventMessage.CREATOR.createFromParcel(parcel); EventMessage fromParcelEventMessage = EventMessage.CREATOR.createFromParcel(parcel);
// Assert equals. // Assert equals.
assertEquals(eventMessage, fromParcelEventMessage); assertThat(fromParcelEventMessage).isEqualTo(eventMessage);
} }
} }

View File

@ -15,14 +15,22 @@
*/ */
package com.google.android.exoplayer2.metadata.id3; package com.google.android.exoplayer2.metadata.id3;
import static com.google.common.truth.Truth.assertThat;
import android.os.Parcel; import android.os.Parcel;
import junit.framework.TestCase; import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/** /**
* Test for {@link ChapterFrame}. * Test for {@link ChapterFrame}.
*/ */
public final class ChapterFrameTest extends TestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class ChapterFrameTest {
@Test
public void testParcelable() { public void testParcelable() {
Id3Frame[] subFrames = new Id3Frame[] { Id3Frame[] subFrames = new Id3Frame[] {
new TextInformationFrame("TIT2", null, "title"), new TextInformationFrame("TIT2", null, "title"),
@ -35,7 +43,7 @@ public final class ChapterFrameTest extends TestCase {
parcel.setDataPosition(0); parcel.setDataPosition(0);
ChapterFrame chapterFrameFromParcel = ChapterFrame.CREATOR.createFromParcel(parcel); ChapterFrame chapterFrameFromParcel = ChapterFrame.CREATOR.createFromParcel(parcel);
assertEquals(chapterFrameToParcel, chapterFrameFromParcel); assertThat(chapterFrameFromParcel).isEqualTo(chapterFrameToParcel);
parcel.recycle(); parcel.recycle();
} }

View File

@ -15,14 +15,22 @@
*/ */
package com.google.android.exoplayer2.metadata.id3; package com.google.android.exoplayer2.metadata.id3;
import static com.google.common.truth.Truth.assertThat;
import android.os.Parcel; import android.os.Parcel;
import junit.framework.TestCase; import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/** /**
* Test for {@link ChapterTocFrame}. * Test for {@link ChapterTocFrame}.
*/ */
public final class ChapterTocFrameTest extends TestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class ChapterTocFrameTest {
@Test
public void testParcelable() { public void testParcelable() {
String[] children = new String[] {"child0", "child1"}; String[] children = new String[] {"child0", "child1"};
Id3Frame[] subFrames = new Id3Frame[] { Id3Frame[] subFrames = new Id3Frame[] {
@ -37,7 +45,7 @@ public final class ChapterTocFrameTest extends TestCase {
parcel.setDataPosition(0); parcel.setDataPosition(0);
ChapterTocFrame chapterTocFrameFromParcel = ChapterTocFrame.CREATOR.createFromParcel(parcel); ChapterTocFrame chapterTocFrameFromParcel = ChapterTocFrame.CREATOR.createFromParcel(parcel);
assertEquals(chapterTocFrameToParcel, chapterTocFrameFromParcel); assertThat(chapterTocFrameFromParcel).isEqualTo(chapterTocFrameToParcel);
parcel.recycle(); parcel.recycle();
} }

View File

@ -15,182 +15,197 @@
*/ */
package com.google.android.exoplayer2.metadata.id3; package com.google.android.exoplayer2.metadata.id3;
import android.test.MoreAsserts; import static com.google.common.truth.Truth.assertThat;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.metadata.Metadata; import com.google.android.exoplayer2.metadata.Metadata;
import com.google.android.exoplayer2.metadata.MetadataDecoderException; import com.google.android.exoplayer2.metadata.MetadataDecoderException;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import junit.framework.TestCase; import java.nio.charset.Charset;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/** /**
* Test for {@link Id3Decoder}. * Test for {@link Id3Decoder}.
*/ */
public final class Id3DecoderTest extends TestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class Id3DecoderTest {
private static final byte[] TAG_HEADER = new byte[] {73, 68, 51, 4, 0, 0, 0, 0, 0, 0}; private static final byte[] TAG_HEADER = new byte[] {73, 68, 51, 4, 0, 0, 0, 0, 0, 0};
private static final int FRAME_HEADER_LENGTH = 10; private static final int FRAME_HEADER_LENGTH = 10;
private static final int ID3_TEXT_ENCODING_UTF_8 = 3; private static final int ID3_TEXT_ENCODING_UTF_8 = 3;
@Test
public void testDecodeTxxxFrame() throws MetadataDecoderException { public void testDecodeTxxxFrame() throws MetadataDecoderException {
byte[] rawId3 = buildSingleFrameTag("TXXX", new byte[] {3, 0, 109, 100, 105, 97, 108, 111, 103, byte[] rawId3 = buildSingleFrameTag("TXXX", new byte[] {3, 0, 109, 100, 105, 97, 108, 111, 103,
95, 86, 73, 78, 68, 73, 67, 79, 49, 53, 50, 55, 54, 54, 52, 95, 115, 116, 97, 114, 116, 0}); 95, 86, 73, 78, 68, 73, 67, 79, 49, 53, 50, 55, 54, 54, 52, 95, 115, 116, 97, 114, 116, 0});
Id3Decoder decoder = new Id3Decoder(); Id3Decoder decoder = new Id3Decoder();
Metadata metadata = decoder.decode(rawId3, rawId3.length); Metadata metadata = decoder.decode(rawId3, rawId3.length);
assertEquals(1, metadata.length()); assertThat(metadata.length()).isEqualTo(1);
TextInformationFrame textInformationFrame = (TextInformationFrame) metadata.get(0); TextInformationFrame textInformationFrame = (TextInformationFrame) metadata.get(0);
assertEquals("TXXX", textInformationFrame.id); assertThat(textInformationFrame.id).isEqualTo("TXXX");
assertEquals("", textInformationFrame.description); assertThat(textInformationFrame.description).isEmpty();
assertEquals("mdialog_VINDICO1527664_start", textInformationFrame.value); assertThat(textInformationFrame.value).isEqualTo("mdialog_VINDICO1527664_start");
// Test empty. // Test empty.
rawId3 = buildSingleFrameTag("TXXX", new byte[0]); rawId3 = buildSingleFrameTag("TXXX", new byte[0]);
metadata = decoder.decode(rawId3, rawId3.length); metadata = decoder.decode(rawId3, rawId3.length);
assertEquals(0, metadata.length()); assertThat(metadata.length()).isEqualTo(0);
// Test encoding byte only. // Test encoding byte only.
rawId3 = buildSingleFrameTag("TXXX", new byte[] {ID3_TEXT_ENCODING_UTF_8}); rawId3 = buildSingleFrameTag("TXXX", new byte[] {ID3_TEXT_ENCODING_UTF_8});
metadata = decoder.decode(rawId3, rawId3.length); metadata = decoder.decode(rawId3, rawId3.length);
assertEquals(1, metadata.length()); assertThat(metadata.length()).isEqualTo(1);
textInformationFrame = (TextInformationFrame) metadata.get(0); textInformationFrame = (TextInformationFrame) metadata.get(0);
assertEquals("TXXX", textInformationFrame.id); assertThat(textInformationFrame.id).isEqualTo("TXXX");
assertEquals("", textInformationFrame.description); assertThat(textInformationFrame.description).isEmpty();
assertEquals("", textInformationFrame.value); assertThat(textInformationFrame.value).isEmpty();
} }
@Test
public void testDecodeTextInformationFrame() throws MetadataDecoderException { public void testDecodeTextInformationFrame() throws MetadataDecoderException {
byte[] rawId3 = buildSingleFrameTag("TIT2", new byte[] {3, 72, 101, 108, 108, 111, 32, 87, 111, byte[] rawId3 = buildSingleFrameTag("TIT2", new byte[] {3, 72, 101, 108, 108, 111, 32, 87, 111,
114, 108, 100, 0}); 114, 108, 100, 0});
Id3Decoder decoder = new Id3Decoder(); Id3Decoder decoder = new Id3Decoder();
Metadata metadata = decoder.decode(rawId3, rawId3.length); Metadata metadata = decoder.decode(rawId3, rawId3.length);
assertEquals(1, metadata.length()); assertThat(metadata.length()).isEqualTo(1);
TextInformationFrame textInformationFrame = (TextInformationFrame) metadata.get(0); TextInformationFrame textInformationFrame = (TextInformationFrame) metadata.get(0);
assertEquals("TIT2", textInformationFrame.id); assertThat(textInformationFrame.id).isEqualTo("TIT2");
assertNull(textInformationFrame.description); assertThat(textInformationFrame.description).isNull();
assertEquals("Hello World", textInformationFrame.value); assertThat(textInformationFrame.value).isEqualTo("Hello World");
// Test empty. // Test empty.
rawId3 = buildSingleFrameTag("TIT2", new byte[0]); rawId3 = buildSingleFrameTag("TIT2", new byte[0]);
metadata = decoder.decode(rawId3, rawId3.length); metadata = decoder.decode(rawId3, rawId3.length);
assertEquals(0, metadata.length()); assertThat(metadata.length()).isEqualTo(0);
// Test encoding byte only. // Test encoding byte only.
rawId3 = buildSingleFrameTag("TIT2", new byte[] {ID3_TEXT_ENCODING_UTF_8}); rawId3 = buildSingleFrameTag("TIT2", new byte[] {ID3_TEXT_ENCODING_UTF_8});
metadata = decoder.decode(rawId3, rawId3.length); metadata = decoder.decode(rawId3, rawId3.length);
assertEquals(1, metadata.length()); assertThat(metadata.length()).isEqualTo(1);
textInformationFrame = (TextInformationFrame) metadata.get(0); textInformationFrame = (TextInformationFrame) metadata.get(0);
assertEquals("TIT2", textInformationFrame.id); assertThat(textInformationFrame.id).isEqualTo("TIT2");
assertEquals(null, textInformationFrame.description); assertThat(textInformationFrame.description).isNull();
assertEquals("", textInformationFrame.value); assertThat(textInformationFrame.value).isEmpty();
} }
@Test
public void testDecodeWxxxFrame() throws MetadataDecoderException { public void testDecodeWxxxFrame() throws MetadataDecoderException {
byte[] rawId3 = buildSingleFrameTag("WXXX", new byte[] {ID3_TEXT_ENCODING_UTF_8, 116, 101, 115, byte[] rawId3 = buildSingleFrameTag("WXXX", new byte[] {ID3_TEXT_ENCODING_UTF_8, 116, 101, 115,
116, 0, 104, 116, 116, 112, 115, 58, 47, 47, 116, 101, 115, 116, 46, 99, 111, 109, 47, 97, 116, 0, 104, 116, 116, 112, 115, 58, 47, 47, 116, 101, 115, 116, 46, 99, 111, 109, 47, 97,
98, 99, 63, 100, 101, 102}); 98, 99, 63, 100, 101, 102});
Id3Decoder decoder = new Id3Decoder(); Id3Decoder decoder = new Id3Decoder();
Metadata metadata = decoder.decode(rawId3, rawId3.length); Metadata metadata = decoder.decode(rawId3, rawId3.length);
assertEquals(1, metadata.length()); assertThat(metadata.length()).isEqualTo(1);
UrlLinkFrame urlLinkFrame = (UrlLinkFrame) metadata.get(0); UrlLinkFrame urlLinkFrame = (UrlLinkFrame) metadata.get(0);
assertEquals("WXXX", urlLinkFrame.id); assertThat(urlLinkFrame.id).isEqualTo("WXXX");
assertEquals("test", urlLinkFrame.description); assertThat(urlLinkFrame.description).isEqualTo("test");
assertEquals("https://test.com/abc?def", urlLinkFrame.url); assertThat(urlLinkFrame.url).isEqualTo("https://test.com/abc?def");
// Test empty. // Test empty.
rawId3 = buildSingleFrameTag("WXXX", new byte[0]); rawId3 = buildSingleFrameTag("WXXX", new byte[0]);
metadata = decoder.decode(rawId3, rawId3.length); metadata = decoder.decode(rawId3, rawId3.length);
assertEquals(0, metadata.length()); assertThat(metadata.length()).isEqualTo(0);
// Test encoding byte only. // Test encoding byte only.
rawId3 = buildSingleFrameTag("WXXX", new byte[] {ID3_TEXT_ENCODING_UTF_8}); rawId3 = buildSingleFrameTag("WXXX", new byte[] {ID3_TEXT_ENCODING_UTF_8});
metadata = decoder.decode(rawId3, rawId3.length); metadata = decoder.decode(rawId3, rawId3.length);
assertEquals(1, metadata.length()); assertThat(metadata.length()).isEqualTo(1);
urlLinkFrame = (UrlLinkFrame) metadata.get(0); urlLinkFrame = (UrlLinkFrame) metadata.get(0);
assertEquals("WXXX", urlLinkFrame.id); assertThat(urlLinkFrame.id).isEqualTo("WXXX");
assertEquals("", urlLinkFrame.description); assertThat(urlLinkFrame.description).isEmpty();
assertEquals("", urlLinkFrame.url); assertThat(urlLinkFrame.url).isEmpty();
} }
@Test
public void testDecodeUrlLinkFrame() throws MetadataDecoderException { public void testDecodeUrlLinkFrame() throws MetadataDecoderException {
byte[] rawId3 = buildSingleFrameTag("WCOM", new byte[] {104, 116, 116, 112, 115, 58, 47, 47, byte[] rawId3 = buildSingleFrameTag("WCOM", new byte[] {104, 116, 116, 112, 115, 58, 47, 47,
116, 101, 115, 116, 46, 99, 111, 109, 47, 97, 98, 99, 63, 100, 101, 102}); 116, 101, 115, 116, 46, 99, 111, 109, 47, 97, 98, 99, 63, 100, 101, 102});
Id3Decoder decoder = new Id3Decoder(); Id3Decoder decoder = new Id3Decoder();
Metadata metadata = decoder.decode(rawId3, rawId3.length); Metadata metadata = decoder.decode(rawId3, rawId3.length);
assertEquals(1, metadata.length()); assertThat(metadata.length()).isEqualTo(1);
UrlLinkFrame urlLinkFrame = (UrlLinkFrame) metadata.get(0); UrlLinkFrame urlLinkFrame = (UrlLinkFrame) metadata.get(0);
assertEquals("WCOM", urlLinkFrame.id); assertThat(urlLinkFrame.id).isEqualTo("WCOM");
assertEquals(null, urlLinkFrame.description); assertThat(urlLinkFrame.description).isNull();
assertEquals("https://test.com/abc?def", urlLinkFrame.url); assertThat(urlLinkFrame.url).isEqualTo("https://test.com/abc?def");
// Test empty. // Test empty.
rawId3 = buildSingleFrameTag("WCOM", new byte[0]); rawId3 = buildSingleFrameTag("WCOM", new byte[0]);
metadata = decoder.decode(rawId3, rawId3.length); metadata = decoder.decode(rawId3, rawId3.length);
assertEquals(1, metadata.length()); assertThat(metadata.length()).isEqualTo(1);
urlLinkFrame = (UrlLinkFrame) metadata.get(0); urlLinkFrame = (UrlLinkFrame) metadata.get(0);
assertEquals("WCOM", urlLinkFrame.id); assertThat(urlLinkFrame.id).isEqualTo("WCOM");
assertEquals(null, urlLinkFrame.description); assertThat(urlLinkFrame.description).isNull();
assertEquals("", urlLinkFrame.url); assertThat(urlLinkFrame.url).isEmpty();
} }
@Test
public void testDecodePrivFrame() throws MetadataDecoderException { public void testDecodePrivFrame() throws MetadataDecoderException {
byte[] rawId3 = buildSingleFrameTag("PRIV", new byte[] {116, 101, 115, 116, 0, 1, 2, 3, 4}); byte[] rawId3 = buildSingleFrameTag("PRIV", new byte[] {116, 101, 115, 116, 0, 1, 2, 3, 4});
Id3Decoder decoder = new Id3Decoder(); Id3Decoder decoder = new Id3Decoder();
Metadata metadata = decoder.decode(rawId3, rawId3.length); Metadata metadata = decoder.decode(rawId3, rawId3.length);
assertEquals(1, metadata.length()); assertThat(metadata.length()).isEqualTo(1);
PrivFrame privFrame = (PrivFrame) metadata.get(0); PrivFrame privFrame = (PrivFrame) metadata.get(0);
assertEquals("test", privFrame.owner); assertThat(privFrame.owner).isEqualTo("test");
MoreAsserts.assertEquals(new byte[] {1, 2, 3, 4}, privFrame.privateData); assertThat(privFrame.privateData).isEqualTo(new byte[]{1, 2, 3, 4});
// Test empty. // Test empty.
rawId3 = buildSingleFrameTag("PRIV", new byte[0]); rawId3 = buildSingleFrameTag("PRIV", new byte[0]);
metadata = decoder.decode(rawId3, rawId3.length); metadata = decoder.decode(rawId3, rawId3.length);
assertEquals(1, metadata.length()); assertThat(metadata.length()).isEqualTo(1);
privFrame = (PrivFrame) metadata.get(0); privFrame = (PrivFrame) metadata.get(0);
assertEquals("", privFrame.owner); assertThat(privFrame.owner).isEmpty();
MoreAsserts.assertEquals(new byte[0], privFrame.privateData); assertThat(privFrame.privateData).isEqualTo(new byte[0]);
} }
@Test
public void testDecodeApicFrame() throws MetadataDecoderException { public void testDecodeApicFrame() throws MetadataDecoderException {
byte[] rawId3 = buildSingleFrameTag("APIC", new byte[] {3, 105, 109, 97, 103, 101, 47, 106, 112, byte[] rawId3 = buildSingleFrameTag("APIC", new byte[] {3, 105, 109, 97, 103, 101, 47, 106, 112,
101, 103, 0, 16, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 0, 1, 2, 3, 4, 5, 6, 7, 101, 103, 0, 16, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 0}); 8, 9, 0});
Id3Decoder decoder = new Id3Decoder(); Id3Decoder decoder = new Id3Decoder();
Metadata metadata = decoder.decode(rawId3, rawId3.length); Metadata metadata = decoder.decode(rawId3, rawId3.length);
assertEquals(1, metadata.length()); assertThat(metadata.length()).isEqualTo(1);
ApicFrame apicFrame = (ApicFrame) metadata.get(0); ApicFrame apicFrame = (ApicFrame) metadata.get(0);
assertEquals("image/jpeg", apicFrame.mimeType); assertThat(apicFrame.mimeType).isEqualTo("image/jpeg");
assertEquals(16, apicFrame.pictureType); assertThat(apicFrame.pictureType).isEqualTo(16);
assertEquals("Hello World", apicFrame.description); assertThat(apicFrame.description).isEqualTo("Hello World");
assertEquals(10, apicFrame.pictureData.length); assertThat(apicFrame.pictureData).hasLength(10);
MoreAsserts.assertEquals(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, apicFrame.pictureData); assertThat(apicFrame.pictureData).isEqualTo(new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 0});
} }
@Test
public void testDecodeCommentFrame() throws MetadataDecoderException { public void testDecodeCommentFrame() throws MetadataDecoderException {
byte[] rawId3 = buildSingleFrameTag("COMM", new byte[] {ID3_TEXT_ENCODING_UTF_8, 101, 110, 103, byte[] rawId3 = buildSingleFrameTag("COMM", new byte[] {ID3_TEXT_ENCODING_UTF_8, 101, 110, 103,
100, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 0, 116, 101, 120, 116, 0}); 100, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 0, 116, 101, 120, 116, 0});
Id3Decoder decoder = new Id3Decoder(); Id3Decoder decoder = new Id3Decoder();
Metadata metadata = decoder.decode(rawId3, rawId3.length); Metadata metadata = decoder.decode(rawId3, rawId3.length);
assertEquals(1, metadata.length()); assertThat(metadata.length()).isEqualTo(1);
CommentFrame commentFrame = (CommentFrame) metadata.get(0); CommentFrame commentFrame = (CommentFrame) metadata.get(0);
assertEquals("eng", commentFrame.language); assertThat(commentFrame.language).isEqualTo("eng");
assertEquals("description", commentFrame.description); assertThat(commentFrame.description).isEqualTo("description");
assertEquals("text", commentFrame.text); assertThat(commentFrame.text).isEqualTo("text");
// Test empty. // Test empty.
rawId3 = buildSingleFrameTag("COMM", new byte[0]); rawId3 = buildSingleFrameTag("COMM", new byte[0]);
metadata = decoder.decode(rawId3, rawId3.length); metadata = decoder.decode(rawId3, rawId3.length);
assertEquals(0, metadata.length()); assertThat(metadata.length()).isEqualTo(0);
// Test language only. // Test language only.
rawId3 = buildSingleFrameTag("COMM", new byte[] {ID3_TEXT_ENCODING_UTF_8, 101, 110, 103}); rawId3 = buildSingleFrameTag("COMM", new byte[] {ID3_TEXT_ENCODING_UTF_8, 101, 110, 103});
metadata = decoder.decode(rawId3, rawId3.length); metadata = decoder.decode(rawId3, rawId3.length);
assertEquals(1, metadata.length()); assertThat(metadata.length()).isEqualTo(1);
commentFrame = (CommentFrame) metadata.get(0); commentFrame = (CommentFrame) metadata.get(0);
assertEquals("eng", commentFrame.language); assertThat(commentFrame.language).isEqualTo("eng");
assertEquals("", commentFrame.description); assertThat(commentFrame.description).isEmpty();
assertEquals("", commentFrame.text); assertThat(commentFrame.text).isEmpty();
} }
private static byte[] buildSingleFrameTag(String frameId, byte[] frameData) { private static byte[] buildSingleFrameTag(String frameId, byte[] frameData) {
byte[] frameIdBytes = frameId.getBytes(); byte[] frameIdBytes = frameId.getBytes(Charset.forName(C.UTF8_NAME));
Assertions.checkState(frameIdBytes.length == 4); Assertions.checkState(frameIdBytes.length == 4);
byte[] tagData = new byte[TAG_HEADER.length + FRAME_HEADER_LENGTH + frameData.length]; byte[] tagData = new byte[TAG_HEADER.length + FRAME_HEADER_LENGTH + frameData.length];

View File

@ -15,29 +15,38 @@
*/ */
package com.google.android.exoplayer2.metadata.scte35; package com.google.android.exoplayer2.metadata.scte35;
import com.google.android.exoplayer2.C; import static com.google.android.exoplayer2.C.TIME_UNSET;
import static com.google.common.truth.Truth.assertThat;
import com.google.android.exoplayer2.metadata.Metadata; import com.google.android.exoplayer2.metadata.Metadata;
import com.google.android.exoplayer2.metadata.MetadataDecoderException; import com.google.android.exoplayer2.metadata.MetadataDecoderException;
import com.google.android.exoplayer2.metadata.MetadataInputBuffer; import com.google.android.exoplayer2.metadata.MetadataInputBuffer;
import com.google.android.exoplayer2.util.TimestampAdjuster; import com.google.android.exoplayer2.util.TimestampAdjuster;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.List; import java.util.List;
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;
/** /**
* Test for {@link SpliceInfoDecoder}. * Test for {@link SpliceInfoDecoder}.
*/ */
public final class SpliceInfoDecoderTest extends TestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class SpliceInfoDecoderTest {
private SpliceInfoDecoder decoder; private SpliceInfoDecoder decoder;
private MetadataInputBuffer inputBuffer; private MetadataInputBuffer inputBuffer;
@Override @Before
public void setUp() { public void setUp() {
decoder = new SpliceInfoDecoder(); decoder = new SpliceInfoDecoder();
inputBuffer = new MetadataInputBuffer(); inputBuffer = new MetadataInputBuffer();
} }
@Test
public void testWrappedAroundTimeSignalCommand() throws MetadataDecoderException { public void testWrappedAroundTimeSignalCommand() throws MetadataDecoderException {
byte[] rawTimeSignalSection = new byte[] { byte[] rawTimeSignalSection = new byte[] {
0, // table_id. 0, // table_id.
@ -59,11 +68,12 @@ public final class SpliceInfoDecoderTest extends TestCase {
// The playback position is 57:15:58.43 approximately. // The playback position is 57:15:58.43 approximately.
// With this offset, the playback position pts before wrapping is 0x451ebf851. // With this offset, the playback position pts before wrapping is 0x451ebf851.
Metadata metadata = feedInputBuffer(rawTimeSignalSection, 0x3000000000L, -0x50000L); Metadata metadata = feedInputBuffer(rawTimeSignalSection, 0x3000000000L, -0x50000L);
assertEquals(1, metadata.length()); assertThat(metadata.length()).isEqualTo(1);
assertEquals(removePtsConversionPrecisionError(0x3001000000L, inputBuffer.subsampleOffsetUs), assertThat(((TimeSignalCommand) metadata.get(0)).playbackPositionUs)
((TimeSignalCommand) metadata.get(0)).playbackPositionUs); .isEqualTo(removePtsConversionPrecisionError(0x3001000000L, inputBuffer.subsampleOffsetUs));
} }
@Test
public void test2SpliceInsertCommands() throws MetadataDecoderException { public void test2SpliceInsertCommands() throws MetadataDecoderException {
byte[] rawSpliceInsertCommand1 = new byte[] { byte[] rawSpliceInsertCommand1 = new byte[] {
0, // table_id. 0, // table_id.
@ -91,18 +101,18 @@ public final class SpliceInfoDecoderTest extends TestCase {
0x00, 0x00, 0x00, 0x00}; // CRC_32 (ignored, check happens at extraction). 0x00, 0x00, 0x00, 0x00}; // CRC_32 (ignored, check happens at extraction).
Metadata metadata = feedInputBuffer(rawSpliceInsertCommand1, 2000000, 3000000); Metadata metadata = feedInputBuffer(rawSpliceInsertCommand1, 2000000, 3000000);
assertEquals(1, metadata.length()); assertThat(metadata.length()).isEqualTo(1);
SpliceInsertCommand command = (SpliceInsertCommand) metadata.get(0); SpliceInsertCommand command = (SpliceInsertCommand) metadata.get(0);
assertEquals(66, command.spliceEventId); assertThat(command.spliceEventId).isEqualTo(66);
assertFalse(command.spliceEventCancelIndicator); assertThat(command.spliceEventCancelIndicator).isFalse();
assertFalse(command.outOfNetworkIndicator); assertThat(command.outOfNetworkIndicator).isFalse();
assertTrue(command.programSpliceFlag); assertThat(command.programSpliceFlag).isTrue();
assertFalse(command.spliceImmediateFlag); assertThat(command.spliceImmediateFlag).isFalse();
assertEquals(3000000, command.programSplicePlaybackPositionUs); assertThat(command.programSplicePlaybackPositionUs).isEqualTo(3000000);
assertEquals(C.TIME_UNSET, command.breakDuration); assertThat(command.breakDuration).isEqualTo(TIME_UNSET);
assertEquals(16, command.uniqueProgramId); assertThat(command.uniqueProgramId).isEqualTo(16);
assertEquals(1, command.availNum); assertThat(command.availNum).isEqualTo(1);
assertEquals(2, command.availsExpected); assertThat(command.availsExpected).isEqualTo(2);
byte[] rawSpliceInsertCommand2 = new byte[] { byte[] rawSpliceInsertCommand2 = new byte[] {
0, // table_id. 0, // table_id.
@ -137,24 +147,24 @@ public final class SpliceInfoDecoderTest extends TestCase {
// By changing the subsample offset we force adjuster reconstruction. // By changing the subsample offset we force adjuster reconstruction.
long subsampleOffset = 1000011; long subsampleOffset = 1000011;
metadata = feedInputBuffer(rawSpliceInsertCommand2, 1000000, subsampleOffset); metadata = feedInputBuffer(rawSpliceInsertCommand2, 1000000, subsampleOffset);
assertEquals(1, metadata.length()); assertThat(metadata.length()).isEqualTo(1);
command = (SpliceInsertCommand) metadata.get(0); command = (SpliceInsertCommand) metadata.get(0);
assertEquals(0xffffffffL, command.spliceEventId); assertThat(command.spliceEventId).isEqualTo(0xffffffffL);
assertFalse(command.spliceEventCancelIndicator); assertThat(command.spliceEventCancelIndicator).isFalse();
assertFalse(command.outOfNetworkIndicator); assertThat(command.outOfNetworkIndicator).isFalse();
assertFalse(command.programSpliceFlag); assertThat(command.programSpliceFlag).isFalse();
assertFalse(command.spliceImmediateFlag); assertThat(command.spliceImmediateFlag).isFalse();
assertEquals(C.TIME_UNSET, command.programSplicePlaybackPositionUs); assertThat(command.programSplicePlaybackPositionUs).isEqualTo(TIME_UNSET);
assertEquals(C.TIME_UNSET, command.breakDuration); assertThat(command.breakDuration).isEqualTo(TIME_UNSET);
List<SpliceInsertCommand.ComponentSplice> componentSplices = command.componentSpliceList; List<SpliceInsertCommand.ComponentSplice> componentSplices = command.componentSpliceList;
assertEquals(2, componentSplices.size()); assertThat(componentSplices).hasSize(2);
assertEquals(16, componentSplices.get(0).componentTag); assertThat(componentSplices.get(0).componentTag).isEqualTo(16);
assertEquals(1000000, componentSplices.get(0).componentSplicePlaybackPositionUs); assertThat(componentSplices.get(0).componentSplicePlaybackPositionUs).isEqualTo(1000000);
assertEquals(17, componentSplices.get(1).componentTag); assertThat(componentSplices.get(1).componentTag).isEqualTo(17);
assertEquals(C.TIME_UNSET, componentSplices.get(1).componentSplicePts); assertThat(componentSplices.get(1).componentSplicePts).isEqualTo(TIME_UNSET);
assertEquals(32, command.uniqueProgramId); assertThat(command.uniqueProgramId).isEqualTo(32);
assertEquals(1, command.availNum); assertThat(command.availNum).isEqualTo(1);
assertEquals(2, command.availsExpected); assertThat(command.availsExpected).isEqualTo(2);
} }
private Metadata feedInputBuffer(byte[] data, long timeUs, long subsampleOffset) private Metadata feedInputBuffer(byte[] data, long timeUs, long subsampleOffset)

View File

@ -0,0 +1,143 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.offline;
import static com.google.common.truth.Truth.assertThat;
import com.google.android.exoplayer2.upstream.DummyDataSource;
import com.google.android.exoplayer2.upstream.cache.Cache;
import com.google.android.exoplayer2.util.ClosedSource;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Unit tests for {@link ProgressiveDownloadAction}.
*/
@ClosedSource(reason = "Not ready yet")
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public class ProgressiveDownloadActionTest {
@Test
public void testDownloadActionIsNotRemoveAction() throws Exception {
ProgressiveDownloadAction action = new ProgressiveDownloadAction("uri", null, false);
assertThat(action.isRemoveAction()).isFalse();
}
@Test
public void testRemoveActionIsRemoveAction() throws Exception {
ProgressiveDownloadAction action2 = new ProgressiveDownloadAction("uri", null, true);
assertThat(action2.isRemoveAction()).isTrue();
}
@Test
public void testCreateDownloader() throws Exception {
MockitoAnnotations.initMocks(this);
ProgressiveDownloadAction action = new ProgressiveDownloadAction("uri", null, false);
DownloaderConstructorHelper constructorHelper = new DownloaderConstructorHelper(
Mockito.mock(Cache.class), DummyDataSource.FACTORY);
assertThat(action.createDownloader(constructorHelper)).isNotNull();
}
@Test
public void testSameUriCacheKeyDifferentAction_IsSameMedia() throws Exception {
ProgressiveDownloadAction action1 = new ProgressiveDownloadAction("uri", null, true);
ProgressiveDownloadAction action2 = new ProgressiveDownloadAction("uri", null, false);
assertThat(action1.isSameMedia(action2)).isTrue();
}
@Test
public void testNullCacheKeyDifferentUriAction_IsNotSameMedia() throws Exception {
ProgressiveDownloadAction action3 = new ProgressiveDownloadAction("uri2", null, true);
ProgressiveDownloadAction action4 = new ProgressiveDownloadAction("uri", null, false);
assertThat(action3.isSameMedia(action4)).isFalse();
}
@Test
public void testSameCacheKeyDifferentUriAction_IsSameMedia() throws Exception {
ProgressiveDownloadAction action5 = new ProgressiveDownloadAction("uri2", "key", true);
ProgressiveDownloadAction action6 = new ProgressiveDownloadAction("uri", "key", false);
assertThat(action5.isSameMedia(action6)).isTrue();
}
@Test
public void testSameUriDifferentCacheKeyAction_IsNotSameMedia() throws Exception {
ProgressiveDownloadAction action7 = new ProgressiveDownloadAction("uri", "key", true);
ProgressiveDownloadAction action8 = new ProgressiveDownloadAction("uri", "key2", false);
assertThat(action7.isSameMedia(action8)).isFalse();
}
@Test
public void testEquals() throws Exception {
ProgressiveDownloadAction action1 = new ProgressiveDownloadAction("uri", null, true);
assertThat(action1.equals(action1)).isTrue();
ProgressiveDownloadAction action2 = new ProgressiveDownloadAction("uri", null, true);
ProgressiveDownloadAction action3 = new ProgressiveDownloadAction("uri", null, true);
assertThat(action2.equals(action3)).isTrue();
ProgressiveDownloadAction action4 = new ProgressiveDownloadAction("uri", null, true);
ProgressiveDownloadAction action5 = new ProgressiveDownloadAction("uri", null, false);
assertThat(action4.equals(action5)).isFalse();
ProgressiveDownloadAction action6 = new ProgressiveDownloadAction("uri", null, true);
ProgressiveDownloadAction action7 = new ProgressiveDownloadAction("uri", "key", true);
assertThat(action6.equals(action7)).isFalse();
ProgressiveDownloadAction action8 = new ProgressiveDownloadAction("uri", "key2", true);
ProgressiveDownloadAction action9 = new ProgressiveDownloadAction("uri", "key", true);
assertThat(action8.equals(action9)).isFalse();
ProgressiveDownloadAction action10 = new ProgressiveDownloadAction("uri", null, true);
ProgressiveDownloadAction action11 = new ProgressiveDownloadAction("uri2", null, true);
assertThat(action10.equals(action11)).isFalse();
}
@Test
public void testSerializerGetType() throws Exception {
ProgressiveDownloadAction action = new ProgressiveDownloadAction("uri", null, false);
assertThat(action.getType()).isNotNull();
}
@Test
public void testSerializerWriteRead() throws Exception {
doTestSerializationRoundTrip(new ProgressiveDownloadAction("uri1", null, false));
doTestSerializationRoundTrip(new ProgressiveDownloadAction("uri2", "key", true));
}
private static void doTestSerializationRoundTrip(ProgressiveDownloadAction action1)
throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(out);
action1.writeToStream(output);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
DataInputStream input = new DataInputStream(in);
DownloadAction action2 = ProgressiveDownloadAction.DESERIALIZER.readFromStream(input);
assertThat(action2).isEqualTo(action1);
}
}

View File

@ -15,7 +15,14 @@
*/ */
package com.google.android.exoplayer2.source; package com.google.android.exoplayer2.source;
import android.test.MoreAsserts; import static com.google.android.exoplayer2.C.RESULT_BUFFER_READ;
import static com.google.android.exoplayer2.C.RESULT_FORMAT_READ;
import static com.google.android.exoplayer2.C.RESULT_NOTHING_READ;
import static com.google.android.exoplayer2.source.SampleQueue.ADVANCE_FAILED;
import static com.google.common.truth.Truth.assertThat;
import static java.lang.Long.MIN_VALUE;
import static java.util.Arrays.copyOfRange;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.FormatHolder; import com.google.android.exoplayer2.FormatHolder;
@ -24,13 +31,19 @@ import com.google.android.exoplayer2.testutil.TestUtil;
import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.DefaultAllocator; import com.google.android.exoplayer2.upstream.DefaultAllocator;
import com.google.android.exoplayer2.util.ParsableByteArray; import com.google.android.exoplayer2.util.ParsableByteArray;
import java.util.Arrays; import org.junit.After;
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;
/** /**
* Test for {@link SampleQueue}. * Test for {@link SampleQueue}.
*/ */
public class SampleQueueTest extends TestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class SampleQueueTest {
private static final int ALLOCATION_SIZE = 16; private static final int ALLOCATION_SIZE = 16;
@ -75,24 +88,23 @@ public class SampleQueueTest extends TestCase {
private FormatHolder formatHolder; private FormatHolder formatHolder;
private DecoderInputBuffer inputBuffer; private DecoderInputBuffer inputBuffer;
@Override @Before
public void setUp() throws Exception { public void setUp() throws Exception {
super.setUp();
allocator = new DefaultAllocator(false, ALLOCATION_SIZE); allocator = new DefaultAllocator(false, ALLOCATION_SIZE);
sampleQueue = new SampleQueue(allocator); sampleQueue = new SampleQueue(allocator);
formatHolder = new FormatHolder(); formatHolder = new FormatHolder();
inputBuffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_NORMAL); inputBuffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_NORMAL);
} }
@Override @After
public void tearDown() throws Exception { public void tearDown() throws Exception {
super.tearDown();
allocator = null; allocator = null;
sampleQueue = null; sampleQueue = null;
formatHolder = null; formatHolder = null;
inputBuffer = null; inputBuffer = null;
} }
@Test
public void testResetReleasesAllocations() { public void testResetReleasesAllocations() {
writeTestData(); writeTestData();
assertAllocationCount(10); assertAllocationCount(10);
@ -100,10 +112,12 @@ public class SampleQueueTest extends TestCase {
assertAllocationCount(0); assertAllocationCount(0);
} }
@Test
public void testReadWithoutWrite() { public void testReadWithoutWrite() {
assertNoSamplesToRead(null); assertNoSamplesToRead(null);
} }
@Test
public void testReadFormatDeduplicated() { public void testReadFormatDeduplicated() {
sampleQueue.format(TEST_FORMAT_1); sampleQueue.format(TEST_FORMAT_1);
assertReadFormat(false, TEST_FORMAT_1); assertReadFormat(false, TEST_FORMAT_1);
@ -115,6 +129,7 @@ public class SampleQueueTest extends TestCase {
assertNoSamplesToRead(TEST_FORMAT_1); assertNoSamplesToRead(TEST_FORMAT_1);
} }
@Test
public void testReadSingleSamples() { public void testReadSingleSamples() {
sampleQueue.sampleData(new ParsableByteArray(TEST_DATA), ALLOCATION_SIZE); sampleQueue.sampleData(new ParsableByteArray(TEST_DATA), ALLOCATION_SIZE);
@ -173,9 +188,10 @@ public class SampleQueueTest extends TestCase {
assertAllocationCount(0); assertAllocationCount(0);
} }
@Test
public void testReadMultiSamples() { public void testReadMultiSamples() {
writeTestData(); writeTestData();
assertEquals(LAST_SAMPLE_TIMESTAMP, sampleQueue.getLargestQueuedTimestampUs()); assertThat(sampleQueue.getLargestQueuedTimestampUs()).isEqualTo(LAST_SAMPLE_TIMESTAMP);
assertAllocationCount(10); assertAllocationCount(10);
assertReadTestData(); assertReadTestData();
assertAllocationCount(10); assertAllocationCount(10);
@ -183,6 +199,7 @@ public class SampleQueueTest extends TestCase {
assertAllocationCount(0); assertAllocationCount(0);
} }
@Test
public void testReadMultiSamplesTwice() { public void testReadMultiSamplesTwice() {
writeTestData(); writeTestData();
writeTestData(); writeTestData();
@ -194,19 +211,21 @@ public class SampleQueueTest extends TestCase {
assertAllocationCount(0); assertAllocationCount(0);
} }
@Test
public void testReadMultiWithRewind() { public void testReadMultiWithRewind() {
writeTestData(); writeTestData();
assertReadTestData(); assertReadTestData();
assertEquals(8, sampleQueue.getReadIndex()); assertThat(sampleQueue.getReadIndex()).isEqualTo(8);
assertAllocationCount(10); assertAllocationCount(10);
// Rewind. // Rewind.
sampleQueue.rewind(); sampleQueue.rewind();
assertAllocationCount(10); assertAllocationCount(10);
// Read again. // Read again.
assertEquals(0, sampleQueue.getReadIndex()); assertThat(sampleQueue.getReadIndex()).isEqualTo(0);
assertReadTestData(); assertReadTestData();
} }
@Test
public void testRewindAfterDiscard() { public void testRewindAfterDiscard() {
writeTestData(); writeTestData();
assertReadTestData(); assertReadTestData();
@ -216,10 +235,11 @@ public class SampleQueueTest extends TestCase {
sampleQueue.rewind(); sampleQueue.rewind();
assertAllocationCount(0); assertAllocationCount(0);
// Can't read again. // Can't read again.
assertEquals(8, sampleQueue.getReadIndex()); assertThat(sampleQueue.getReadIndex()).isEqualTo(8);
assertReadEndOfStream(false); assertReadEndOfStream(false);
} }
@Test
public void testAdvanceToEnd() { public void testAdvanceToEnd() {
writeTestData(); writeTestData();
sampleQueue.advanceToEnd(); sampleQueue.advanceToEnd();
@ -233,6 +253,7 @@ public class SampleQueueTest extends TestCase {
assertNoSamplesToRead(TEST_FORMAT_2); assertNoSamplesToRead(TEST_FORMAT_2);
} }
@Test
public void testAdvanceToEndRetainsUnassignedData() { public void testAdvanceToEndRetainsUnassignedData() {
sampleQueue.format(TEST_FORMAT_1); sampleQueue.format(TEST_FORMAT_1);
sampleQueue.sampleData(new ParsableByteArray(TEST_DATA), ALLOCATION_SIZE); sampleQueue.sampleData(new ParsableByteArray(TEST_DATA), ALLOCATION_SIZE);
@ -256,56 +277,62 @@ public class SampleQueueTest extends TestCase {
assertAllocationCount(0); assertAllocationCount(0);
} }
@Test
public void testAdvanceToBeforeBuffer() { public void testAdvanceToBeforeBuffer() {
writeTestData(); writeTestData();
int skipCount = sampleQueue.advanceTo(TEST_SAMPLE_TIMESTAMPS[0] - 1, true, false); int skipCount = sampleQueue.advanceTo(TEST_SAMPLE_TIMESTAMPS[0] - 1, true, false);
// Should fail and have no effect. // Should fail and have no effect.
assertEquals(SampleQueue.ADVANCE_FAILED, skipCount); assertThat(skipCount).isEqualTo(ADVANCE_FAILED);
assertReadTestData(); assertReadTestData();
assertNoSamplesToRead(TEST_FORMAT_2); assertNoSamplesToRead(TEST_FORMAT_2);
} }
@Test
public void testAdvanceToStartOfBuffer() { public void testAdvanceToStartOfBuffer() {
writeTestData(); writeTestData();
int skipCount = sampleQueue.advanceTo(TEST_SAMPLE_TIMESTAMPS[0], true, false); int skipCount = sampleQueue.advanceTo(TEST_SAMPLE_TIMESTAMPS[0], true, false);
// Should succeed but have no effect (we're already at the first frame). // Should succeed but have no effect (we're already at the first frame).
assertEquals(0, skipCount); assertThat(skipCount).isEqualTo(0);
assertReadTestData(); assertReadTestData();
assertNoSamplesToRead(TEST_FORMAT_2); assertNoSamplesToRead(TEST_FORMAT_2);
} }
@Test
public void testAdvanceToEndOfBuffer() { public void testAdvanceToEndOfBuffer() {
writeTestData(); writeTestData();
int skipCount = sampleQueue.advanceTo(LAST_SAMPLE_TIMESTAMP, true, false); int skipCount = sampleQueue.advanceTo(LAST_SAMPLE_TIMESTAMP, true, false);
// Should succeed and skip to 2nd keyframe (the 4th frame). // Should succeed and skip to 2nd keyframe (the 4th frame).
assertEquals(4, skipCount); assertThat(skipCount).isEqualTo(4);
assertReadTestData(null, TEST_DATA_SECOND_KEYFRAME_INDEX); assertReadTestData(null, TEST_DATA_SECOND_KEYFRAME_INDEX);
assertNoSamplesToRead(TEST_FORMAT_2); assertNoSamplesToRead(TEST_FORMAT_2);
} }
@Test
public void testAdvanceToAfterBuffer() { public void testAdvanceToAfterBuffer() {
writeTestData(); writeTestData();
int skipCount = sampleQueue.advanceTo(LAST_SAMPLE_TIMESTAMP + 1, true, false); int skipCount = sampleQueue.advanceTo(LAST_SAMPLE_TIMESTAMP + 1, true, false);
// Should fail and have no effect. // Should fail and have no effect.
assertEquals(SampleQueue.ADVANCE_FAILED, skipCount); assertThat(skipCount).isEqualTo(ADVANCE_FAILED);
assertReadTestData(); assertReadTestData();
assertNoSamplesToRead(TEST_FORMAT_2); assertNoSamplesToRead(TEST_FORMAT_2);
} }
@Test
public void testAdvanceToAfterBufferAllowed() { public void testAdvanceToAfterBufferAllowed() {
writeTestData(); writeTestData();
int skipCount = sampleQueue.advanceTo(LAST_SAMPLE_TIMESTAMP + 1, true, true); int skipCount = sampleQueue.advanceTo(LAST_SAMPLE_TIMESTAMP + 1, true, true);
// Should succeed and skip to 2nd keyframe (the 4th frame). // Should succeed and skip to 2nd keyframe (the 4th frame).
assertEquals(4, skipCount); assertThat(skipCount).isEqualTo(4);
assertReadTestData(null, TEST_DATA_SECOND_KEYFRAME_INDEX); assertReadTestData(null, TEST_DATA_SECOND_KEYFRAME_INDEX);
assertNoSamplesToRead(TEST_FORMAT_2); assertNoSamplesToRead(TEST_FORMAT_2);
} }
@Test
public void testDiscardToEnd() { public void testDiscardToEnd() {
writeTestData(); writeTestData();
// Should discard everything. // Should discard everything.
sampleQueue.discardToEnd(); sampleQueue.discardToEnd();
assertEquals(8, sampleQueue.getReadIndex()); assertThat(sampleQueue.getReadIndex()).isEqualTo(8);
assertAllocationCount(0); assertAllocationCount(0);
// We should still be able to read the upstream format. // We should still be able to read the upstream format.
assertReadFormat(false, TEST_FORMAT_2); assertReadFormat(false, TEST_FORMAT_2);
@ -314,17 +341,18 @@ public class SampleQueueTest extends TestCase {
assertReadTestData(TEST_FORMAT_2); assertReadTestData(TEST_FORMAT_2);
} }
@Test
public void testDiscardToStopAtReadPosition() { public void testDiscardToStopAtReadPosition() {
writeTestData(); writeTestData();
// Shouldn't discard anything. // Shouldn't discard anything.
sampleQueue.discardTo(LAST_SAMPLE_TIMESTAMP, false, true); sampleQueue.discardTo(LAST_SAMPLE_TIMESTAMP, false, true);
assertEquals(0, sampleQueue.getReadIndex()); assertThat(sampleQueue.getReadIndex()).isEqualTo(0);
assertAllocationCount(10); assertAllocationCount(10);
// Read the first sample. // Read the first sample.
assertReadTestData(null, 0, 1); assertReadTestData(null, 0, 1);
// Shouldn't discard anything. // Shouldn't discard anything.
sampleQueue.discardTo(TEST_SAMPLE_TIMESTAMPS[1] - 1, false, true); sampleQueue.discardTo(TEST_SAMPLE_TIMESTAMPS[1] - 1, false, true);
assertEquals(1, sampleQueue.getReadIndex()); assertThat(sampleQueue.getReadIndex()).isEqualTo(1);
assertAllocationCount(10); assertAllocationCount(10);
// Should discard the read sample. // Should discard the read sample.
sampleQueue.discardTo(TEST_SAMPLE_TIMESTAMPS[1], false, true); sampleQueue.discardTo(TEST_SAMPLE_TIMESTAMPS[1], false, true);
@ -334,7 +362,7 @@ public class SampleQueueTest extends TestCase {
assertAllocationCount(9); assertAllocationCount(9);
// Should be able to read the remaining samples. // Should be able to read the remaining samples.
assertReadTestData(TEST_FORMAT_1, 1, 7); assertReadTestData(TEST_FORMAT_1, 1, 7);
assertEquals(8, sampleQueue.getReadIndex()); assertThat(sampleQueue.getReadIndex()).isEqualTo(8);
// Should discard up to the second last sample // Should discard up to the second last sample
sampleQueue.discardTo(LAST_SAMPLE_TIMESTAMP - 1, false, true); sampleQueue.discardTo(LAST_SAMPLE_TIMESTAMP - 1, false, true);
assertAllocationCount(3); assertAllocationCount(3);
@ -343,20 +371,22 @@ public class SampleQueueTest extends TestCase {
assertAllocationCount(1); assertAllocationCount(1);
} }
@Test
public void testDiscardToDontStopAtReadPosition() { public void testDiscardToDontStopAtReadPosition() {
writeTestData(); writeTestData();
// Shouldn't discard anything. // Shouldn't discard anything.
sampleQueue.discardTo(TEST_SAMPLE_TIMESTAMPS[1] - 1, false, false); sampleQueue.discardTo(TEST_SAMPLE_TIMESTAMPS[1] - 1, false, false);
assertEquals(0, sampleQueue.getReadIndex()); assertThat(sampleQueue.getReadIndex()).isEqualTo(0);
assertAllocationCount(10); assertAllocationCount(10);
// Should discard the first sample. // Should discard the first sample.
sampleQueue.discardTo(TEST_SAMPLE_TIMESTAMPS[1], false, false); sampleQueue.discardTo(TEST_SAMPLE_TIMESTAMPS[1], false, false);
assertEquals(1, sampleQueue.getReadIndex()); assertThat(sampleQueue.getReadIndex()).isEqualTo(1);
assertAllocationCount(9); assertAllocationCount(9);
// Should be able to read the remaining samples. // Should be able to read the remaining samples.
assertReadTestData(TEST_FORMAT_1, 1, 7); assertReadTestData(TEST_FORMAT_1, 1, 7);
} }
@Test
public void testDiscardUpstream() { public void testDiscardUpstream() {
writeTestData(); writeTestData();
sampleQueue.discardUpstreamSamples(8); sampleQueue.discardUpstreamSamples(8);
@ -381,6 +411,7 @@ public class SampleQueueTest extends TestCase {
assertNoSamplesToRead(TEST_FORMAT_2); assertNoSamplesToRead(TEST_FORMAT_2);
} }
@Test
public void testDiscardUpstreamMulti() { public void testDiscardUpstreamMulti() {
writeTestData(); writeTestData();
sampleQueue.discardUpstreamSamples(4); sampleQueue.discardUpstreamSamples(4);
@ -391,6 +422,7 @@ public class SampleQueueTest extends TestCase {
assertNoSamplesToRead(TEST_FORMAT_2); assertNoSamplesToRead(TEST_FORMAT_2);
} }
@Test
public void testDiscardUpstreamBeforeRead() { public void testDiscardUpstreamBeforeRead() {
writeTestData(); writeTestData();
sampleQueue.discardUpstreamSamples(4); sampleQueue.discardUpstreamSamples(4);
@ -400,6 +432,7 @@ public class SampleQueueTest extends TestCase {
assertNoSamplesToRead(TEST_FORMAT_2); assertNoSamplesToRead(TEST_FORMAT_2);
} }
@Test
public void testDiscardUpstreamAfterRead() { public void testDiscardUpstreamAfterRead() {
writeTestData(); writeTestData();
assertReadTestData(null, 0, 3); assertReadTestData(null, 0, 3);
@ -421,41 +454,44 @@ public class SampleQueueTest extends TestCase {
assertNoSamplesToRead(TEST_FORMAT_2); assertNoSamplesToRead(TEST_FORMAT_2);
} }
@Test
public void testLargestQueuedTimestampWithDiscardUpstream() { public void testLargestQueuedTimestampWithDiscardUpstream() {
writeTestData(); writeTestData();
assertEquals(LAST_SAMPLE_TIMESTAMP, sampleQueue.getLargestQueuedTimestampUs()); assertThat(sampleQueue.getLargestQueuedTimestampUs()).isEqualTo(LAST_SAMPLE_TIMESTAMP);
sampleQueue.discardUpstreamSamples(TEST_SAMPLE_TIMESTAMPS.length - 1); sampleQueue.discardUpstreamSamples(TEST_SAMPLE_TIMESTAMPS.length - 1);
// Discarding from upstream should reduce the largest timestamp. // Discarding from upstream should reduce the largest timestamp.
assertEquals(TEST_SAMPLE_TIMESTAMPS[TEST_SAMPLE_TIMESTAMPS.length - 2], assertThat(sampleQueue.getLargestQueuedTimestampUs())
sampleQueue.getLargestQueuedTimestampUs()); .isEqualTo(TEST_SAMPLE_TIMESTAMPS[TEST_SAMPLE_TIMESTAMPS.length - 2]);
sampleQueue.discardUpstreamSamples(0); sampleQueue.discardUpstreamSamples(0);
// Discarding everything from upstream without reading should unset the largest timestamp. // Discarding everything from upstream without reading should unset the largest timestamp.
assertEquals(Long.MIN_VALUE, sampleQueue.getLargestQueuedTimestampUs()); assertThat(sampleQueue.getLargestQueuedTimestampUs()).isEqualTo(MIN_VALUE);
} }
@Test
public void testLargestQueuedTimestampWithDiscardUpstreamDecodeOrder() { public void testLargestQueuedTimestampWithDiscardUpstreamDecodeOrder() {
long[] decodeOrderTimestamps = new long[] {0, 3000, 2000, 1000, 4000, 7000, 6000, 5000}; long[] decodeOrderTimestamps = new long[] {0, 3000, 2000, 1000, 4000, 7000, 6000, 5000};
writeTestData(TEST_DATA, TEST_SAMPLE_SIZES, TEST_SAMPLE_OFFSETS, decodeOrderTimestamps, writeTestData(TEST_DATA, TEST_SAMPLE_SIZES, TEST_SAMPLE_OFFSETS, decodeOrderTimestamps,
TEST_SAMPLE_FORMATS, TEST_SAMPLE_FLAGS); TEST_SAMPLE_FORMATS, TEST_SAMPLE_FLAGS);
assertEquals(7000, sampleQueue.getLargestQueuedTimestampUs()); assertThat(sampleQueue.getLargestQueuedTimestampUs()).isEqualTo(7000);
sampleQueue.discardUpstreamSamples(TEST_SAMPLE_TIMESTAMPS.length - 2); sampleQueue.discardUpstreamSamples(TEST_SAMPLE_TIMESTAMPS.length - 2);
// Discarding the last two samples should not change the largest timestamp, due to the decode // Discarding the last two samples should not change the largest timestamp, due to the decode
// ordering of the timestamps. // ordering of the timestamps.
assertEquals(7000, sampleQueue.getLargestQueuedTimestampUs()); assertThat(sampleQueue.getLargestQueuedTimestampUs()).isEqualTo(7000);
sampleQueue.discardUpstreamSamples(TEST_SAMPLE_TIMESTAMPS.length - 3); sampleQueue.discardUpstreamSamples(TEST_SAMPLE_TIMESTAMPS.length - 3);
// Once a third sample is discarded, the largest timestamp should have changed. // Once a third sample is discarded, the largest timestamp should have changed.
assertEquals(4000, sampleQueue.getLargestQueuedTimestampUs()); assertThat(sampleQueue.getLargestQueuedTimestampUs()).isEqualTo(4000);
sampleQueue.discardUpstreamSamples(0); sampleQueue.discardUpstreamSamples(0);
// Discarding everything from upstream without reading should unset the largest timestamp. // Discarding everything from upstream without reading should unset the largest timestamp.
assertEquals(Long.MIN_VALUE, sampleQueue.getLargestQueuedTimestampUs()); assertThat(sampleQueue.getLargestQueuedTimestampUs()).isEqualTo(MIN_VALUE);
} }
@Test
public void testLargestQueuedTimestampWithRead() { public void testLargestQueuedTimestampWithRead() {
writeTestData(); writeTestData();
assertEquals(LAST_SAMPLE_TIMESTAMP, sampleQueue.getLargestQueuedTimestampUs()); assertThat(sampleQueue.getLargestQueuedTimestampUs()).isEqualTo(LAST_SAMPLE_TIMESTAMP);
assertReadTestData(); assertReadTestData();
// Reading everything should not reduce the largest timestamp. // Reading everything should not reduce the largest timestamp.
assertEquals(LAST_SAMPLE_TIMESTAMP, sampleQueue.getLargestQueuedTimestampUs()); assertThat(sampleQueue.getLargestQueuedTimestampUs()).isEqualTo(LAST_SAMPLE_TIMESTAMP);
} }
// Internal methods. // Internal methods.
@ -580,9 +616,9 @@ public class SampleQueueTest extends TestCase {
private void assertReadNothing(boolean formatRequired) { private void assertReadNothing(boolean formatRequired) {
clearFormatHolderAndInputBuffer(); clearFormatHolderAndInputBuffer();
int result = sampleQueue.read(formatHolder, inputBuffer, formatRequired, false, 0); int result = sampleQueue.read(formatHolder, inputBuffer, formatRequired, false, 0);
assertEquals(C.RESULT_NOTHING_READ, result); assertThat(result).isEqualTo(RESULT_NOTHING_READ);
// formatHolder should not be populated. // formatHolder should not be populated.
assertNull(formatHolder.format); assertThat(formatHolder.format).isNull();
// inputBuffer should not be populated. // inputBuffer should not be populated.
assertInputBufferContainsNoSampleData(); assertInputBufferContainsNoSampleData();
assertInputBufferHasNoDefaultFlagsSet(); assertInputBufferHasNoDefaultFlagsSet();
@ -597,14 +633,14 @@ public class SampleQueueTest extends TestCase {
private void assertReadEndOfStream(boolean formatRequired) { private void assertReadEndOfStream(boolean formatRequired) {
clearFormatHolderAndInputBuffer(); clearFormatHolderAndInputBuffer();
int result = sampleQueue.read(formatHolder, inputBuffer, formatRequired, true, 0); int result = sampleQueue.read(formatHolder, inputBuffer, formatRequired, true, 0);
assertEquals(C.RESULT_BUFFER_READ, result); assertThat(result).isEqualTo(RESULT_BUFFER_READ);
// formatHolder should not be populated. // formatHolder should not be populated.
assertNull(formatHolder.format); assertThat(formatHolder.format).isNull();
// inputBuffer should not contain sample data, but end of stream flag should be set. // inputBuffer should not contain sample data, but end of stream flag should be set.
assertInputBufferContainsNoSampleData(); assertInputBufferContainsNoSampleData();
assertTrue(inputBuffer.isEndOfStream()); assertThat(inputBuffer.isEndOfStream()).isTrue();
assertFalse(inputBuffer.isDecodeOnly()); assertThat(inputBuffer.isDecodeOnly()).isFalse();
assertFalse(inputBuffer.isEncrypted()); assertThat(inputBuffer.isEncrypted()).isFalse();
} }
/** /**
@ -617,9 +653,9 @@ public class SampleQueueTest extends TestCase {
private void assertReadFormat(boolean formatRequired, Format format) { private void assertReadFormat(boolean formatRequired, Format format) {
clearFormatHolderAndInputBuffer(); clearFormatHolderAndInputBuffer();
int result = sampleQueue.read(formatHolder, inputBuffer, formatRequired, false, 0); int result = sampleQueue.read(formatHolder, inputBuffer, formatRequired, false, 0);
assertEquals(C.RESULT_FORMAT_READ, result); assertThat(result).isEqualTo(RESULT_FORMAT_READ);
// formatHolder should be populated. // formatHolder should be populated.
assertEquals(format, formatHolder.format); assertThat(formatHolder.format).isEqualTo(format);
// inputBuffer should not be populated. // inputBuffer should not be populated.
assertInputBufferContainsNoSampleData(); assertInputBufferContainsNoSampleData();
assertInputBufferHasNoDefaultFlagsSet(); assertInputBufferHasNoDefaultFlagsSet();
@ -639,19 +675,19 @@ public class SampleQueueTest extends TestCase {
int length) { int length) {
clearFormatHolderAndInputBuffer(); clearFormatHolderAndInputBuffer();
int result = sampleQueue.read(formatHolder, inputBuffer, false, false, 0); int result = sampleQueue.read(formatHolder, inputBuffer, false, false, 0);
assertEquals(C.RESULT_BUFFER_READ, result); assertThat(result).isEqualTo(RESULT_BUFFER_READ);
// formatHolder should not be populated. // formatHolder should not be populated.
assertNull(formatHolder.format); assertThat(formatHolder.format).isNull();
// inputBuffer should be populated. // inputBuffer should be populated.
assertEquals(timeUs, inputBuffer.timeUs); assertThat(inputBuffer.timeUs).isEqualTo(timeUs);
assertEquals(isKeyframe, inputBuffer.isKeyFrame()); assertThat(inputBuffer.isKeyFrame()).isEqualTo(isKeyframe);
assertFalse(inputBuffer.isDecodeOnly()); assertThat(inputBuffer.isDecodeOnly()).isFalse();
assertFalse(inputBuffer.isEncrypted()); assertThat(inputBuffer.isEncrypted()).isFalse();
inputBuffer.flip(); inputBuffer.flip();
assertEquals(length, inputBuffer.data.limit()); assertThat(inputBuffer.data.limit()).isEqualTo(length);
byte[] readData = new byte[length]; byte[] readData = new byte[length];
inputBuffer.data.get(readData); inputBuffer.data.get(readData);
MoreAsserts.assertEquals(Arrays.copyOfRange(sampleData, offset, offset + length), readData); assertThat(readData).isEqualTo(copyOfRange(sampleData, offset, offset + length));
} }
/** /**
@ -660,7 +696,7 @@ public class SampleQueueTest extends TestCase {
* @param count The expected number of allocations. * @param count The expected number of allocations.
*/ */
private void assertAllocationCount(int count) { private void assertAllocationCount(int count) {
assertEquals(ALLOCATION_SIZE * count, allocator.getTotalBytesAllocated()); assertThat(allocator.getTotalBytesAllocated()).isEqualTo(ALLOCATION_SIZE * count);
} }
/** /**
@ -671,13 +707,13 @@ public class SampleQueueTest extends TestCase {
return; return;
} }
inputBuffer.flip(); inputBuffer.flip();
assertEquals(0, inputBuffer.data.limit()); assertThat(inputBuffer.data.limit()).isEqualTo(0);
} }
private void assertInputBufferHasNoDefaultFlagsSet() { private void assertInputBufferHasNoDefaultFlagsSet() {
assertFalse(inputBuffer.isEndOfStream()); assertThat(inputBuffer.isEndOfStream()).isFalse();
assertFalse(inputBuffer.isDecodeOnly()); assertThat(inputBuffer.isDecodeOnly()).isFalse();
assertFalse(inputBuffer.isEncrypted()); assertThat(inputBuffer.isEncrypted()).isFalse();
} }
private void clearFormatHolderAndInputBuffer() { private void clearFormatHolderAndInputBuffer() {

View File

@ -15,18 +15,27 @@
*/ */
package com.google.android.exoplayer2.source; package com.google.android.exoplayer2.source;
import static com.google.android.exoplayer2.C.INDEX_UNSET;
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.source.ShuffleOrder.DefaultShuffleOrder; import com.google.android.exoplayer2.source.ShuffleOrder.DefaultShuffleOrder;
import com.google.android.exoplayer2.source.ShuffleOrder.UnshuffledShuffleOrder; import com.google.android.exoplayer2.source.ShuffleOrder.UnshuffledShuffleOrder;
import junit.framework.TestCase; import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/** /**
* Unit test for {@link ShuffleOrder}. * Unit test for {@link ShuffleOrder}.
*/ */
public final class ShuffleOrderTest extends TestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class ShuffleOrderTest {
public static final long RANDOM_SEED = 1234567890L; public static final long RANDOM_SEED = 1234567890L;
@Test
public void testDefaultShuffleOrder() { public void testDefaultShuffleOrder() {
assertShuffleOrderCorrectness(new DefaultShuffleOrder(0, RANDOM_SEED), 0); assertShuffleOrderCorrectness(new DefaultShuffleOrder(0, RANDOM_SEED), 0);
assertShuffleOrderCorrectness(new DefaultShuffleOrder(1, RANDOM_SEED), 1); assertShuffleOrderCorrectness(new DefaultShuffleOrder(1, RANDOM_SEED), 1);
@ -44,6 +53,7 @@ public final class ShuffleOrderTest extends TestCase {
testCloneAndRemove(new DefaultShuffleOrder(1, RANDOM_SEED), 0); testCloneAndRemove(new DefaultShuffleOrder(1, RANDOM_SEED), 0);
} }
@Test
public void testUnshuffledShuffleOrder() { public void testUnshuffledShuffleOrder() {
assertShuffleOrderCorrectness(new UnshuffledShuffleOrder(0), 0); assertShuffleOrderCorrectness(new UnshuffledShuffleOrder(0), 0);
assertShuffleOrderCorrectness(new UnshuffledShuffleOrder(1), 1); assertShuffleOrderCorrectness(new UnshuffledShuffleOrder(1), 1);
@ -61,35 +71,36 @@ public final class ShuffleOrderTest extends TestCase {
testCloneAndRemove(new UnshuffledShuffleOrder(1), 0); testCloneAndRemove(new UnshuffledShuffleOrder(1), 0);
} }
@Test
public void testUnshuffledShuffleOrderIsUnshuffled() { public void testUnshuffledShuffleOrderIsUnshuffled() {
ShuffleOrder shuffleOrder = new UnshuffledShuffleOrder(5); ShuffleOrder shuffleOrder = new UnshuffledShuffleOrder(5);
assertEquals(0, shuffleOrder.getFirstIndex()); assertThat(shuffleOrder.getFirstIndex()).isEqualTo(0);
assertEquals(4, shuffleOrder.getLastIndex()); assertThat(shuffleOrder.getLastIndex()).isEqualTo(4);
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
assertEquals(i + 1, shuffleOrder.getNextIndex(i)); assertThat(shuffleOrder.getNextIndex(i)).isEqualTo(i + 1);
} }
} }
private static void assertShuffleOrderCorrectness(ShuffleOrder shuffleOrder, int length) { private static void assertShuffleOrderCorrectness(ShuffleOrder shuffleOrder, int length) {
assertEquals(length, shuffleOrder.getLength()); assertThat(shuffleOrder.getLength()).isEqualTo(length);
if (length == 0) { if (length == 0) {
assertEquals(C.INDEX_UNSET, shuffleOrder.getFirstIndex()); assertThat(shuffleOrder.getFirstIndex()).isEqualTo(INDEX_UNSET);
assertEquals(C.INDEX_UNSET, shuffleOrder.getLastIndex()); assertThat(shuffleOrder.getLastIndex()).isEqualTo(INDEX_UNSET);
} else { } else {
int[] indices = new int[length]; int[] indices = new int[length];
indices[0] = shuffleOrder.getFirstIndex(); indices[0] = shuffleOrder.getFirstIndex();
assertEquals(C.INDEX_UNSET, shuffleOrder.getPreviousIndex(indices[0])); assertThat(shuffleOrder.getPreviousIndex(indices[0])).isEqualTo(INDEX_UNSET);
for (int i = 1; i < length; i++) { for (int i = 1; i < length; i++) {
indices[i] = shuffleOrder.getNextIndex(indices[i - 1]); indices[i] = shuffleOrder.getNextIndex(indices[i - 1]);
assertEquals(indices[i - 1], shuffleOrder.getPreviousIndex(indices[i])); assertThat(shuffleOrder.getPreviousIndex(indices[i])).isEqualTo(indices[i - 1]);
for (int j = 0; j < i; j++) { for (int j = 0; j < i; j++) {
assertTrue(indices[i] != indices[j]); assertThat(indices[i] != indices[j]).isTrue();
} }
} }
assertEquals(indices[length - 1], shuffleOrder.getLastIndex()); assertThat(shuffleOrder.getLastIndex()).isEqualTo(indices[length - 1]);
assertEquals(C.INDEX_UNSET, shuffleOrder.getNextIndex(indices[length - 1])); assertThat(shuffleOrder.getNextIndex(indices[length - 1])).isEqualTo(INDEX_UNSET);
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
assertTrue(indices[i] >= 0 && indices[i] < length); assertThat(indices[i] >= 0 && indices[i] < length).isTrue();
} }
} }
} }
@ -107,7 +118,7 @@ public final class ShuffleOrderTest extends TestCase {
while (newNextIndex >= position && newNextIndex < position + count) { while (newNextIndex >= position && newNextIndex < position + count) {
newNextIndex = newOrder.getNextIndex(newNextIndex); newNextIndex = newOrder.getNextIndex(newNextIndex);
} }
assertEquals(expectedNextIndex, newNextIndex); assertThat(newNextIndex).isEqualTo(expectedNextIndex);
} }
} }
@ -127,7 +138,7 @@ public final class ShuffleOrderTest extends TestCase {
expectedNextIndex--; expectedNextIndex--;
} }
int newNextIndex = newOrder.getNextIndex(i < position ? i : i - 1); int newNextIndex = newOrder.getNextIndex(i < position ? i : i - 1);
assertEquals(expectedNextIndex, newNextIndex); assertThat(newNextIndex).isEqualTo(expectedNextIndex);
} }
} }

View File

@ -15,43 +15,62 @@
*/ */
package com.google.android.exoplayer2.text.ttml; package com.google.android.exoplayer2.text.ttml;
import static android.graphics.Color.BLACK;
import static android.graphics.Color.RED;
import static android.graphics.Color.YELLOW;
import static com.google.android.exoplayer2.text.ttml.TtmlRenderUtil.resolveStyle;
import static com.google.android.exoplayer2.text.ttml.TtmlStyle.STYLE_BOLD;
import static com.google.android.exoplayer2.text.ttml.TtmlStyle.STYLE_BOLD_ITALIC;
import static com.google.common.truth.Truth.assertThat;
import android.graphics.Color; import android.graphics.Color;
import android.test.InstrumentationTestCase;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/** /**
* Unit test for <code>TtmlRenderUtil</code> * Unit test for {@link TtmlRenderUtil}.
*/ */
public class TtmlRenderUtilTest extends InstrumentationTestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class TtmlRenderUtilTest {
@Test
public void testResolveStyleNoStyleAtAll() { public void testResolveStyleNoStyleAtAll() {
assertNull(TtmlRenderUtil.resolveStyle(null, null, null)); assertThat(resolveStyle(null, null, null)).isNull();
} }
@Test
public void testResolveStyleSingleReferentialStyle() { public void testResolveStyleSingleReferentialStyle() {
Map<String, TtmlStyle> globalStyles = getGlobalStyles(); Map<String, TtmlStyle> globalStyles = getGlobalStyles();
String[] styleIds = {"s0"}; String[] styleIds = {"s0"};
assertSame(globalStyles.get("s0"), assertThat(TtmlRenderUtil.resolveStyle(null, styleIds, globalStyles))
TtmlRenderUtil.resolveStyle(null, styleIds, globalStyles)); .isSameAs(globalStyles.get("s0"));
} }
@Test
public void testResolveStyleMultipleReferentialStyles() { public void testResolveStyleMultipleReferentialStyles() {
Map<String, TtmlStyle> globalStyles = getGlobalStyles(); Map<String, TtmlStyle> globalStyles = getGlobalStyles();
String[] styleIds = {"s0", "s1"}; String[] styleIds = {"s0", "s1"};
TtmlStyle resolved = TtmlRenderUtil.resolveStyle(null, styleIds, globalStyles); TtmlStyle resolved = TtmlRenderUtil.resolveStyle(null, styleIds, globalStyles);
assertNotSame(globalStyles.get("s0"), resolved); assertThat(resolved).isNotSameAs(globalStyles.get("s0"));
assertNotSame(globalStyles.get("s1"), resolved); assertThat(resolved).isNotSameAs(globalStyles.get("s1"));
assertNull(resolved.getId()); assertThat(resolved.getId()).isNull();
// inherited from s0 // inherited from s0
assertEquals(Color.BLACK, resolved.getBackgroundColor()); assertThat(resolved.getBackgroundColor()).isEqualTo(BLACK);
// inherited from s1 // inherited from s1
assertEquals(Color.RED, resolved.getFontColor()); assertThat(resolved.getFontColor()).isEqualTo(RED);
// merged from s0 and s1 // merged from s0 and s1
assertEquals(TtmlStyle.STYLE_BOLD_ITALIC, resolved.getStyle()); assertThat(resolved.getStyle()).isEqualTo(STYLE_BOLD_ITALIC);
} }
@Test
public void testResolveMergeSingleReferentialStyleIntoInlineStyle() { public void testResolveMergeSingleReferentialStyleIntoInlineStyle() {
Map<String, TtmlStyle> globalStyles = getGlobalStyles(); Map<String, TtmlStyle> globalStyles = getGlobalStyles();
String[] styleIds = {"s0"}; String[] styleIds = {"s0"};
@ -59,15 +78,15 @@ public class TtmlRenderUtilTest extends InstrumentationTestCase {
style.setBackgroundColor(Color.YELLOW); style.setBackgroundColor(Color.YELLOW);
TtmlStyle resolved = TtmlRenderUtil.resolveStyle(style, styleIds, globalStyles); TtmlStyle resolved = TtmlRenderUtil.resolveStyle(style, styleIds, globalStyles);
assertSame(style, resolved); assertThat(resolved).isSameAs(style);
// inline attribute not overridden // inline attribute not overridden
assertEquals(Color.YELLOW, resolved.getBackgroundColor()); assertThat(resolved.getBackgroundColor()).isEqualTo(YELLOW);
// inherited from referential style // inherited from referential style
assertEquals(TtmlStyle.STYLE_BOLD, resolved.getStyle()); assertThat(resolved.getStyle()).isEqualTo(STYLE_BOLD);
} }
@Test
public void testResolveMergeMultipleReferentialStylesIntoInlineStyle() { public void testResolveMergeMultipleReferentialStylesIntoInlineStyle() {
Map<String, TtmlStyle> globalStyles = getGlobalStyles(); Map<String, TtmlStyle> globalStyles = getGlobalStyles();
String[] styleIds = {"s0", "s1"}; String[] styleIds = {"s0", "s1"};
@ -75,20 +94,21 @@ public class TtmlRenderUtilTest extends InstrumentationTestCase {
style.setBackgroundColor(Color.YELLOW); style.setBackgroundColor(Color.YELLOW);
TtmlStyle resolved = TtmlRenderUtil.resolveStyle(style, styleIds, globalStyles); TtmlStyle resolved = TtmlRenderUtil.resolveStyle(style, styleIds, globalStyles);
assertSame(style, resolved); assertThat(resolved).isSameAs(style);
// inline attribute not overridden // inline attribute not overridden
assertEquals(Color.YELLOW, resolved.getBackgroundColor()); assertThat(resolved.getBackgroundColor()).isEqualTo(YELLOW);
// inherited from both referential style // inherited from both referential style
assertEquals(TtmlStyle.STYLE_BOLD_ITALIC, resolved.getStyle()); assertThat(resolved.getStyle()).isEqualTo(STYLE_BOLD_ITALIC);
} }
@Test
public void testResolveStyleOnlyInlineStyle() { public void testResolveStyleOnlyInlineStyle() {
TtmlStyle inlineStyle = new TtmlStyle(); TtmlStyle inlineStyle = new TtmlStyle();
assertSame(inlineStyle, TtmlRenderUtil.resolveStyle(inlineStyle, null, null)); assertThat(TtmlRenderUtil.resolveStyle(inlineStyle, null, null)).isSameAs(inlineStyle);
} }
private Map<String, TtmlStyle> getGlobalStyles() { private static Map<String, TtmlStyle> getGlobalStyles() {
Map<String, TtmlStyle> globalStyles = new HashMap<>(); Map<String, TtmlStyle> globalStyles = new HashMap<>();
TtmlStyle s0 = new TtmlStyle(); TtmlStyle s0 = new TtmlStyle();

View File

@ -0,0 +1,155 @@
/*
* 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.
*/
package com.google.android.exoplayer2.text.ttml;
import static android.graphics.Color.BLACK;
import static android.graphics.Color.WHITE;
import static com.google.android.exoplayer2.text.ttml.TtmlStyle.STYLE_BOLD;
import static com.google.android.exoplayer2.text.ttml.TtmlStyle.STYLE_BOLD_ITALIC;
import static com.google.android.exoplayer2.text.ttml.TtmlStyle.STYLE_ITALIC;
import static com.google.android.exoplayer2.text.ttml.TtmlStyle.STYLE_NORMAL;
import static com.google.android.exoplayer2.text.ttml.TtmlStyle.UNSPECIFIED;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import android.graphics.Color;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/** Unit test for {@link TtmlStyle}. */
@RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class TtmlStyleTest {
private static final String FONT_FAMILY = "serif";
private static final String ID = "id";
public static final int FOREGROUND_COLOR = Color.WHITE;
public static final int BACKGROUND_COLOR = Color.BLACK;
private TtmlStyle style;
@Before
public void setUp() throws Exception {
style = new TtmlStyle();
}
@Test
public void testInheritStyle() {
style.inherit(createAncestorStyle());
assertWithMessage("id must not be inherited").that(style.getId()).isNull();
assertThat(style.isUnderline()).isTrue();
assertThat(style.isLinethrough()).isTrue();
assertThat(style.getStyle()).isEqualTo(STYLE_BOLD_ITALIC);
assertThat(style.getFontFamily()).isEqualTo(FONT_FAMILY);
assertThat(style.getFontColor()).isEqualTo(WHITE);
assertWithMessage("do not inherit backgroundColor").that(style.hasBackgroundColor()).isFalse();
}
@Test
public void testChainStyle() {
style.chain(createAncestorStyle());
assertWithMessage("id must not be inherited").that(style.getId()).isNull();
assertThat(style.isUnderline()).isTrue();
assertThat(style.isLinethrough()).isTrue();
assertThat(style.getStyle()).isEqualTo(STYLE_BOLD_ITALIC);
assertThat(style.getFontFamily()).isEqualTo(FONT_FAMILY);
assertThat(style.getFontColor()).isEqualTo(FOREGROUND_COLOR);
// do inherit backgroundColor when chaining
assertWithMessage("do not inherit backgroundColor when chaining")
.that(style.getBackgroundColor()).isEqualTo(BACKGROUND_COLOR);
}
private static TtmlStyle createAncestorStyle() {
TtmlStyle ancestor = new TtmlStyle();
ancestor.setId(ID);
ancestor.setItalic(true);
ancestor.setBold(true);
ancestor.setBackgroundColor(BACKGROUND_COLOR);
ancestor.setFontColor(FOREGROUND_COLOR);
ancestor.setLinethrough(true);
ancestor.setUnderline(true);
ancestor.setFontFamily(FONT_FAMILY);
return ancestor;
}
@Test
public void testStyle() {
assertThat(style.getStyle()).isEqualTo(UNSPECIFIED);
style.setItalic(true);
assertThat(style.getStyle()).isEqualTo(STYLE_ITALIC);
style.setBold(true);
assertThat(style.getStyle()).isEqualTo(STYLE_BOLD_ITALIC);
style.setItalic(false);
assertThat(style.getStyle()).isEqualTo(STYLE_BOLD);
style.setBold(false);
assertThat(style.getStyle()).isEqualTo(STYLE_NORMAL);
}
@Test
public void testLinethrough() {
assertThat(style.isLinethrough()).isFalse();
style.setLinethrough(true);
assertThat(style.isLinethrough()).isTrue();
style.setLinethrough(false);
assertThat(style.isLinethrough()).isFalse();
}
@Test
public void testUnderline() {
assertThat(style.isUnderline()).isFalse();
style.setUnderline(true);
assertThat(style.isUnderline()).isTrue();
style.setUnderline(false);
assertThat(style.isUnderline()).isFalse();
}
@Test
public void testFontFamily() {
assertThat(style.getFontFamily()).isNull();
style.setFontFamily(FONT_FAMILY);
assertThat(style.getFontFamily()).isEqualTo(FONT_FAMILY);
style.setFontFamily(null);
assertThat(style.getFontFamily()).isNull();
}
@Test
public void testColor() {
assertThat(style.hasFontColor()).isFalse();
style.setFontColor(Color.BLACK);
assertThat(style.getFontColor()).isEqualTo(BLACK);
assertThat(style.hasFontColor()).isTrue();
}
@Test
public void testBackgroundColor() {
assertThat(style.hasBackgroundColor()).isFalse();
style.setBackgroundColor(Color.BLACK);
assertThat(style.getBackgroundColor()).isEqualTo(BLACK);
assertThat(style.hasBackgroundColor()).isTrue();
}
@Test
public void testId() {
assertThat(style.getId()).isNull();
style.setId(ID);
assertThat(style.getId()).isEqualTo(ID);
style.setId(null);
assertThat(style.getId()).isNull();
}
}

View File

@ -15,22 +15,32 @@
*/ */
package com.google.android.exoplayer2.text.webvtt; package com.google.android.exoplayer2.text.webvtt;
import android.test.InstrumentationTestCase; import static com.google.android.exoplayer2.text.webvtt.CssParser.parseNextToken;
import static com.google.common.truth.Truth.assertThat;
import com.google.android.exoplayer2.util.ParsableByteArray; import com.google.android.exoplayer2.util.ParsableByteArray;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/** /**
* Unit test for {@link CssParser}. * Unit test for {@link CssParser}.
*/ */
public final class CssParserTest extends InstrumentationTestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class CssParserTest {
private CssParser parser; private CssParser parser;
@Override @Before
public void setUp() { public void setUp() {
parser = new CssParser(); parser = new CssParser();
} }
@Test
public void testSkipWhitespacesAndComments() { public void testSkipWhitespacesAndComments() {
// Skip only whitespaces // Skip only whitespaces
String skipOnlyWhitespaces = " \t\r\n\f End of skip\n /* */"; String skipOnlyWhitespaces = " \t\r\n\f End of skip\n /* */";
@ -53,6 +63,7 @@ public final class CssParserTest extends InstrumentationTestCase {
assertSkipsToEndOfSkip(null, skipEverything); assertSkipsToEndOfSkip(null, skipEverything);
} }
@Test
public void testGetInputLimit() { public void testGetInputLimit() {
// \r After 3 lines. // \r After 3 lines.
String threeLinesThen3Cr = "One Line\nThen other\rAnd finally\r\r\r"; String threeLinesThen3Cr = "One Line\nThen other\rAnd finally\r\r\r";
@ -78,6 +89,7 @@ public final class CssParserTest extends InstrumentationTestCase {
assertInputLimit(null, ""); assertInputLimit(null, "");
} }
@Test
public void testParseMethodSimpleInput() { public void testParseMethodSimpleInput() {
String styleBlock1 = " ::cue { color : black; background-color: PapayaWhip }"; String styleBlock1 = " ::cue { color : black; background-color: PapayaWhip }";
WebvttCssStyle expectedStyle = new WebvttCssStyle(); WebvttCssStyle expectedStyle = new WebvttCssStyle();
@ -96,6 +108,7 @@ public final class CssParserTest extends InstrumentationTestCase {
assertParserProduces(expectedStyle, styleBlock3); assertParserProduces(expectedStyle, styleBlock3);
} }
@Test
public void testMultiplePropertiesInBlock() { public void testMultiplePropertiesInBlock() {
String styleBlock = "::cue(#id){text-decoration:underline; background-color:green;" String styleBlock = "::cue(#id){text-decoration:underline; background-color:green;"
+ "color:red; font-family:Courier; font-weight:bold}"; + "color:red; font-family:Courier; font-weight:bold}";
@ -110,6 +123,7 @@ public final class CssParserTest extends InstrumentationTestCase {
assertParserProduces(expectedStyle, styleBlock); assertParserProduces(expectedStyle, styleBlock);
} }
@Test
public void testRgbaColorExpression() { public void testRgbaColorExpression() {
String styleBlock = "::cue(#rgb){background-color: rgba(\n10/* Ugly color */,11\t, 12\n,.1);" String styleBlock = "::cue(#rgb){background-color: rgba(\n10/* Ugly color */,11\t, 12\n,.1);"
+ "color:rgb(1,1,\n1)}"; + "color:rgb(1,1,\n1)}";
@ -121,59 +135,62 @@ public final class CssParserTest extends InstrumentationTestCase {
assertParserProduces(expectedStyle, styleBlock); assertParserProduces(expectedStyle, styleBlock);
} }
@Test
public void testGetNextToken() { public void testGetNextToken() {
String stringInput = " lorem:ipsum\n{dolor}#sit,amet;lorem:ipsum\r\t\f\ndolor(())\n"; String stringInput = " lorem:ipsum\n{dolor}#sit,amet;lorem:ipsum\r\t\f\ndolor(())\n";
ParsableByteArray input = new ParsableByteArray(Util.getUtf8Bytes(stringInput)); ParsableByteArray input = new ParsableByteArray(Util.getUtf8Bytes(stringInput));
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
assertEquals("lorem", CssParser.parseNextToken(input, builder)); assertThat(parseNextToken(input, builder)).isEqualTo("lorem");
assertEquals(":", CssParser.parseNextToken(input, builder)); assertThat(parseNextToken(input, builder)).isEqualTo(":");
assertEquals("ipsum", CssParser.parseNextToken(input, builder)); assertThat(parseNextToken(input, builder)).isEqualTo("ipsum");
assertEquals("{", CssParser.parseNextToken(input, builder)); assertThat(parseNextToken(input, builder)).isEqualTo("{");
assertEquals("dolor", CssParser.parseNextToken(input, builder)); assertThat(parseNextToken(input, builder)).isEqualTo("dolor");
assertEquals("}", CssParser.parseNextToken(input, builder)); assertThat(parseNextToken(input, builder)).isEqualTo("}");
assertEquals("#sit", CssParser.parseNextToken(input, builder)); assertThat(parseNextToken(input, builder)).isEqualTo("#sit");
assertEquals(",", CssParser.parseNextToken(input, builder)); assertThat(parseNextToken(input, builder)).isEqualTo(",");
assertEquals("amet", CssParser.parseNextToken(input, builder)); assertThat(parseNextToken(input, builder)).isEqualTo("amet");
assertEquals(";", CssParser.parseNextToken(input, builder)); assertThat(parseNextToken(input, builder)).isEqualTo(";");
assertEquals("lorem", CssParser.parseNextToken(input, builder)); assertThat(parseNextToken(input, builder)).isEqualTo("lorem");
assertEquals(":", CssParser.parseNextToken(input, builder)); assertThat(parseNextToken(input, builder)).isEqualTo(":");
assertEquals("ipsum", CssParser.parseNextToken(input, builder)); assertThat(parseNextToken(input, builder)).isEqualTo("ipsum");
assertEquals("dolor", CssParser.parseNextToken(input, builder)); assertThat(parseNextToken(input, builder)).isEqualTo("dolor");
assertEquals("(", CssParser.parseNextToken(input, builder)); assertThat(parseNextToken(input, builder)).isEqualTo("(");
assertEquals("(", CssParser.parseNextToken(input, builder)); assertThat(parseNextToken(input, builder)).isEqualTo("(");
assertEquals(")", CssParser.parseNextToken(input, builder)); assertThat(parseNextToken(input, builder)).isEqualTo(")");
assertEquals(")", CssParser.parseNextToken(input, builder)); assertThat(parseNextToken(input, builder)).isEqualTo(")");
assertEquals(null, CssParser.parseNextToken(input, builder)); assertThat(parseNextToken(input, builder)).isNull();
} }
@Test
public void testStyleScoreSystem() { public void testStyleScoreSystem() {
WebvttCssStyle style = new WebvttCssStyle(); WebvttCssStyle style = new WebvttCssStyle();
// Universal selector. // Universal selector.
assertEquals(1, style.getSpecificityScore("", "", new String[0], "")); assertThat(style.getSpecificityScore("", "", new String[0], "")).isEqualTo(1);
// Class match without tag match. // Class match without tag match.
style.setTargetClasses(new String[] { "class1", "class2"}); style.setTargetClasses(new String[] { "class1", "class2"});
assertEquals(8, style.getSpecificityScore("", "", new String[] { "class1", "class2", "class3" }, assertThat(style.getSpecificityScore("", "", new String[]{"class1", "class2", "class3"},
"")); "")).isEqualTo(8);
// Class and tag match // Class and tag match
style.setTargetTagName("b"); style.setTargetTagName("b");
assertEquals(10, style.getSpecificityScore("", "b", assertThat(style.getSpecificityScore("", "b",
new String[] { "class1", "class2", "class3" }, "")); new String[]{"class1", "class2", "class3"}, "")).isEqualTo(10);
// Class insufficiency. // Class insufficiency.
assertEquals(0, style.getSpecificityScore("", "b", new String[] { "class1", "class" }, "")); assertThat(style.getSpecificityScore("", "b", new String[]{"class1", "class"}, ""))
.isEqualTo(0);
// Voice, classes and tag match. // Voice, classes and tag match.
style.setTargetVoice("Manuel Cráneo"); style.setTargetVoice("Manuel Cráneo");
assertEquals(14, style.getSpecificityScore("", "b", assertThat(style.getSpecificityScore("", "b",
new String[] { "class1", "class2", "class3" }, "Manuel Cráneo")); new String[]{"class1", "class2", "class3"}, "Manuel Cráneo")).isEqualTo(14);
// Voice mismatch. // Voice mismatch.
assertEquals(0, style.getSpecificityScore(null, "b", assertThat(style.getSpecificityScore(null, "b",
new String[] { "class1", "class2", "class3" }, "Manuel Craneo")); new String[]{"class1", "class2", "class3"}, "Manuel Craneo")).isEqualTo(0);
// Id, voice, classes and tag match. // Id, voice, classes and tag match.
style.setTargetId("id"); style.setTargetId("id");
assertEquals(0x40000000 + 14, style.getSpecificityScore("id", "b", assertThat(style.getSpecificityScore("id", "b",
new String[] { "class1", "class2", "class3" }, "Manuel Cráneo")); new String[]{"class1", "class2", "class3"}, "Manuel Cráneo")).isEqualTo(0x40000000 + 14);
// Id mismatch. // Id mismatch.
assertEquals(0, style.getSpecificityScore("id1", "b", assertThat(style.getSpecificityScore("id1", "b",
new String[] { "class1", "class2", "class3" }, "")); new String[]{"class1", "class2", "class3"}, "")).isEqualTo(0);
} }
// Utility methods. // Utility methods.
@ -181,34 +198,34 @@ public final class CssParserTest extends InstrumentationTestCase {
private void assertSkipsToEndOfSkip(String expectedLine, String s) { private void assertSkipsToEndOfSkip(String expectedLine, String s) {
ParsableByteArray input = new ParsableByteArray(Util.getUtf8Bytes(s)); ParsableByteArray input = new ParsableByteArray(Util.getUtf8Bytes(s));
CssParser.skipWhitespaceAndComments(input); CssParser.skipWhitespaceAndComments(input);
assertEquals(expectedLine, input.readLine()); assertThat(input.readLine()).isEqualTo(expectedLine);
} }
private void assertInputLimit(String expectedLine, String s) { private void assertInputLimit(String expectedLine, String s) {
ParsableByteArray input = new ParsableByteArray(Util.getUtf8Bytes(s)); ParsableByteArray input = new ParsableByteArray(Util.getUtf8Bytes(s));
CssParser.skipStyleBlock(input); CssParser.skipStyleBlock(input);
assertEquals(expectedLine, input.readLine()); assertThat(input.readLine()).isEqualTo(expectedLine);
} }
private void assertParserProduces(WebvttCssStyle expected, private void assertParserProduces(WebvttCssStyle expected,
String styleBlock){ String styleBlock){
ParsableByteArray input = new ParsableByteArray(Util.getUtf8Bytes(styleBlock)); ParsableByteArray input = new ParsableByteArray(Util.getUtf8Bytes(styleBlock));
WebvttCssStyle actualElem = parser.parseBlock(input); WebvttCssStyle actualElem = parser.parseBlock(input);
assertEquals(expected.hasBackgroundColor(), actualElem.hasBackgroundColor()); assertThat(actualElem.hasBackgroundColor()).isEqualTo(expected.hasBackgroundColor());
if (expected.hasBackgroundColor()) { if (expected.hasBackgroundColor()) {
assertEquals(expected.getBackgroundColor(), actualElem.getBackgroundColor()); assertThat(actualElem.getBackgroundColor()).isEqualTo(expected.getBackgroundColor());
} }
assertEquals(expected.hasFontColor(), actualElem.hasFontColor()); assertThat(actualElem.hasFontColor()).isEqualTo(expected.hasFontColor());
if (expected.hasFontColor()) { if (expected.hasFontColor()) {
assertEquals(expected.getFontColor(), actualElem.getFontColor()); assertThat(actualElem.getFontColor()).isEqualTo(expected.getFontColor());
} }
assertEquals(expected.getFontFamily(), actualElem.getFontFamily()); assertThat(actualElem.getFontFamily()).isEqualTo(expected.getFontFamily());
assertEquals(expected.getFontSize(), actualElem.getFontSize()); assertThat(actualElem.getFontSize()).isEqualTo(expected.getFontSize());
assertEquals(expected.getFontSizeUnit(), actualElem.getFontSizeUnit()); assertThat(actualElem.getFontSizeUnit()).isEqualTo(expected.getFontSizeUnit());
assertEquals(expected.getStyle(), actualElem.getStyle()); assertThat(actualElem.getStyle()).isEqualTo(expected.getStyle());
assertEquals(expected.isLinethrough(), actualElem.isLinethrough()); assertThat(actualElem.isLinethrough()).isEqualTo(expected.isLinethrough());
assertEquals(expected.isUnderline(), actualElem.isUnderline()); assertThat(actualElem.isUnderline()).isEqualTo(expected.isUnderline());
assertEquals(expected.getTextAlign(), actualElem.getTextAlign()); assertThat(actualElem.getTextAlign()).isEqualTo(expected.getTextAlign());
} }
} }

View File

@ -15,16 +15,24 @@
*/ */
package com.google.android.exoplayer2.text.webvtt; package com.google.android.exoplayer2.text.webvtt;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import com.google.android.exoplayer2.text.Cue; import com.google.android.exoplayer2.text.Cue;
import com.google.android.exoplayer2.text.Subtitle; import com.google.android.exoplayer2.text.Subtitle;
import com.google.android.exoplayer2.text.SubtitleDecoderException; import com.google.android.exoplayer2.text.SubtitleDecoderException;
import java.util.List; import java.util.List;
import junit.framework.TestCase; import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/** /**
* Unit test for {@link Mp4WebvttDecoder}. * Unit test for {@link Mp4WebvttDecoder}.
*/ */
public final class Mp4WebvttDecoderTest extends TestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class Mp4WebvttDecoderTest {
private static final byte[] SINGLE_CUE_SAMPLE = { private static final byte[] SINGLE_CUE_SAMPLE = {
0x00, 0x00, 0x00, 0x1C, // Size 0x00, 0x00, 0x00, 0x1C, // Size
@ -79,6 +87,7 @@ public final class Mp4WebvttDecoderTest extends TestCase {
// Positive tests. // Positive tests.
@Test
public void testSingleCueSample() throws SubtitleDecoderException { public void testSingleCueSample() throws SubtitleDecoderException {
Mp4WebvttDecoder decoder = new Mp4WebvttDecoder(); Mp4WebvttDecoder decoder = new Mp4WebvttDecoder();
Subtitle result = decoder.decode(SINGLE_CUE_SAMPLE, SINGLE_CUE_SAMPLE.length, false); Subtitle result = decoder.decode(SINGLE_CUE_SAMPLE, SINGLE_CUE_SAMPLE.length, false);
@ -86,6 +95,7 @@ public final class Mp4WebvttDecoderTest extends TestCase {
assertMp4WebvttSubtitleEquals(result, expectedCue); assertMp4WebvttSubtitleEquals(result, expectedCue);
} }
@Test
public void testTwoCuesSample() throws SubtitleDecoderException { public void testTwoCuesSample() throws SubtitleDecoderException {
Mp4WebvttDecoder decoder = new Mp4WebvttDecoder(); Mp4WebvttDecoder decoder = new Mp4WebvttDecoder();
Subtitle result = decoder.decode(DOUBLE_CUE_SAMPLE, DOUBLE_CUE_SAMPLE.length, false); Subtitle result = decoder.decode(DOUBLE_CUE_SAMPLE, DOUBLE_CUE_SAMPLE.length, false);
@ -94,6 +104,7 @@ public final class Mp4WebvttDecoderTest extends TestCase {
assertMp4WebvttSubtitleEquals(result, firstExpectedCue, secondExpectedCue); assertMp4WebvttSubtitleEquals(result, firstExpectedCue, secondExpectedCue);
} }
@Test
public void testNoCueSample() throws SubtitleDecoderException { public void testNoCueSample() throws SubtitleDecoderException {
Mp4WebvttDecoder decoder = new Mp4WebvttDecoder(); Mp4WebvttDecoder decoder = new Mp4WebvttDecoder();
Subtitle result = decoder.decode(NO_CUE_SAMPLE, NO_CUE_SAMPLE.length, false); Subtitle result = decoder.decode(NO_CUE_SAMPLE, NO_CUE_SAMPLE.length, false);
@ -102,6 +113,7 @@ public final class Mp4WebvttDecoderTest extends TestCase {
// Negative tests. // Negative tests.
@Test
public void testSampleWithIncompleteHeader() { public void testSampleWithIncompleteHeader() {
Mp4WebvttDecoder decoder = new Mp4WebvttDecoder(); Mp4WebvttDecoder decoder = new Mp4WebvttDecoder();
try { try {
@ -122,10 +134,10 @@ public final class Mp4WebvttDecoderTest extends TestCase {
* @param expectedCues The expected {@link Cue}s. * @param expectedCues The expected {@link Cue}s.
*/ */
private static void assertMp4WebvttSubtitleEquals(Subtitle subtitle, Cue... expectedCues) { private static void assertMp4WebvttSubtitleEquals(Subtitle subtitle, Cue... expectedCues) {
assertEquals(1, subtitle.getEventTimeCount()); assertThat(subtitle.getEventTimeCount()).isEqualTo(1);
assertEquals(0, subtitle.getEventTime(0)); assertThat(subtitle.getEventTime(0)).isEqualTo(0);
List<Cue> subtitleCues = subtitle.getCues(0); List<Cue> subtitleCues = subtitle.getCues(0);
assertEquals(expectedCues.length, subtitleCues.size()); assertThat(subtitleCues).hasSize(expectedCues.length);
for (int i = 0; i < subtitleCues.size(); i++) { for (int i = 0; i < subtitleCues.size(); i++) {
assertCueEquals(expectedCues[i], subtitleCues.get(i)); assertCueEquals(expectedCues[i], subtitleCues.get(i));
} }
@ -135,14 +147,14 @@ public final class Mp4WebvttDecoderTest extends TestCase {
* Asserts that two cues are equal. * Asserts that two cues are equal.
*/ */
private static void assertCueEquals(Cue expected, Cue actual) { private static void assertCueEquals(Cue expected, Cue actual) {
assertEquals(expected.line, actual.line); assertThat(actual.line).isEqualTo(expected.line);
assertEquals(expected.lineAnchor, actual.lineAnchor); assertThat(actual.lineAnchor).isEqualTo(expected.lineAnchor);
assertEquals(expected.lineType, actual.lineType); assertThat(actual.lineType).isEqualTo(expected.lineType);
assertEquals(expected.position, actual.position); assertThat(actual.position).isEqualTo(expected.position);
assertEquals(expected.positionAnchor, actual.positionAnchor); assertThat(actual.positionAnchor).isEqualTo(expected.positionAnchor);
assertEquals(expected.size, actual.size); assertThat(actual.size).isEqualTo(expected.size);
assertEquals(expected.text.toString(), actual.text.toString()); assertThat(actual.text.toString()).isEqualTo(expected.text.toString());
assertEquals(expected.textAlignment, actual.textAlignment); assertThat(actual.textAlignment).isEqualTo(expected.textAlignment);
} }
} }

View File

@ -15,209 +15,235 @@
*/ */
package com.google.android.exoplayer2.text.webvtt; package com.google.android.exoplayer2.text.webvtt;
import static android.graphics.Typeface.BOLD;
import static android.graphics.Typeface.ITALIC;
import static com.google.common.truth.Truth.assertThat;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.test.InstrumentationTestCase;
import android.text.Spanned; import android.text.Spanned;
import android.text.style.StyleSpan; import android.text.style.StyleSpan;
import android.text.style.UnderlineSpan; import android.text.style.UnderlineSpan;
import java.util.Collections; import java.util.Collections;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/** /**
* Unit test for {@link WebvttCueParser}. * Unit test for {@link WebvttCueParser}.
*/ */
public final class WebvttCueParserTest extends InstrumentationTestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class WebvttCueParserTest {
@Test
public void testParseStrictValidClassesAndTrailingTokens() throws Exception { public void testParseStrictValidClassesAndTrailingTokens() throws Exception {
Spanned text = parseCueText("<v.first.loud Esme>" Spanned text = parseCueText("<v.first.loud Esme>"
+ "This <u.style1.style2 some stuff>is</u> text with <b.foo><i.bar>html</i></b> tags"); + "This <u.style1.style2 some stuff>is</u> text with <b.foo><i.bar>html</i></b> tags");
assertEquals("This is text with html tags", text.toString()); assertThat(text.toString()).isEqualTo("This is text with html tags");
UnderlineSpan[] underlineSpans = getSpans(text, UnderlineSpan.class); UnderlineSpan[] underlineSpans = getSpans(text, UnderlineSpan.class);
StyleSpan[] styleSpans = getSpans(text, StyleSpan.class); StyleSpan[] styleSpans = getSpans(text, StyleSpan.class);
assertEquals(1, underlineSpans.length); assertThat(underlineSpans).hasLength(1);
assertEquals(2, styleSpans.length); assertThat(styleSpans).hasLength(2);
assertEquals(Typeface.ITALIC, styleSpans[0].getStyle()); assertThat(styleSpans[0].getStyle()).isEqualTo(ITALIC);
assertEquals(Typeface.BOLD, styleSpans[1].getStyle()); assertThat(styleSpans[1].getStyle()).isEqualTo(BOLD);
assertEquals(5, text.getSpanStart(underlineSpans[0])); assertThat(text.getSpanStart(underlineSpans[0])).isEqualTo(5);
assertEquals(7, text.getSpanEnd(underlineSpans[0])); assertThat(text.getSpanEnd(underlineSpans[0])).isEqualTo(7);
assertEquals(18, text.getSpanStart(styleSpans[0])); assertThat(text.getSpanStart(styleSpans[0])).isEqualTo(18);
assertEquals(18, text.getSpanStart(styleSpans[1])); assertThat(text.getSpanStart(styleSpans[1])).isEqualTo(18);
assertEquals(22, text.getSpanEnd(styleSpans[0])); assertThat(text.getSpanEnd(styleSpans[0])).isEqualTo(22);
assertEquals(22, text.getSpanEnd(styleSpans[1])); assertThat(text.getSpanEnd(styleSpans[1])).isEqualTo(22);
} }
@Test
public void testParseStrictValidUnsupportedTagsStrippedOut() throws Exception { public void testParseStrictValidUnsupportedTagsStrippedOut() throws Exception {
Spanned text = parseCueText("<v.first.loud Esme>This <unsupported>is</unsupported> text with " Spanned text = parseCueText("<v.first.loud Esme>This <unsupported>is</unsupported> text with "
+ "<notsupp><invalid>html</invalid></notsupp> tags"); + "<notsupp><invalid>html</invalid></notsupp> tags");
assertEquals("This is text with html tags", text.toString()); assertThat(text.toString()).isEqualTo("This is text with html tags");
assertEquals(0, getSpans(text, UnderlineSpan.class).length); assertThat(getSpans(text, UnderlineSpan.class)).hasLength(0);
assertEquals(0, getSpans(text, StyleSpan.class).length); assertThat(getSpans(text, StyleSpan.class)).hasLength(0);
} }
@Test
public void testParseWellFormedUnclosedEndAtCueEnd() throws Exception { public void testParseWellFormedUnclosedEndAtCueEnd() throws Exception {
Spanned text = parseCueText("An <u some trailing stuff>unclosed u tag with " Spanned text = parseCueText("An <u some trailing stuff>unclosed u tag with "
+ "<i>italic</i> inside"); + "<i>italic</i> inside");
assertEquals("An unclosed u tag with italic inside", text.toString()); assertThat(text.toString()).isEqualTo("An unclosed u tag with italic inside");
UnderlineSpan[] underlineSpans = getSpans(text, UnderlineSpan.class); UnderlineSpan[] underlineSpans = getSpans(text, UnderlineSpan.class);
StyleSpan[] styleSpans = getSpans(text, StyleSpan.class); StyleSpan[] styleSpans = getSpans(text, StyleSpan.class);
assertEquals(1, underlineSpans.length); assertThat(underlineSpans).hasLength(1);
assertEquals(1, styleSpans.length); assertThat(styleSpans).hasLength(1);
assertEquals(Typeface.ITALIC, styleSpans[0].getStyle()); assertThat(styleSpans[0].getStyle()).isEqualTo(ITALIC);
assertEquals(3, text.getSpanStart(underlineSpans[0])); assertThat(text.getSpanStart(underlineSpans[0])).isEqualTo(3);
assertEquals(23, text.getSpanStart(styleSpans[0])); assertThat(text.getSpanStart(styleSpans[0])).isEqualTo(23);
assertEquals(29, text.getSpanEnd(styleSpans[0])); assertThat(text.getSpanEnd(styleSpans[0])).isEqualTo(29);
assertEquals(36, text.getSpanEnd(underlineSpans[0])); assertThat(text.getSpanEnd(underlineSpans[0])).isEqualTo(36);
} }
@Test
public void testParseWellFormedUnclosedEndAtParent() throws Exception { public void testParseWellFormedUnclosedEndAtParent() throws Exception {
Spanned text = parseCueText("An unclosed u tag with <i><u>underline and italic</i> inside"); Spanned text = parseCueText("An unclosed u tag with <i><u>underline and italic</i> inside");
assertEquals("An unclosed u tag with underline and italic inside", text.toString()); assertThat(text.toString()).isEqualTo("An unclosed u tag with underline and italic inside");
UnderlineSpan[] underlineSpans = getSpans(text, UnderlineSpan.class); UnderlineSpan[] underlineSpans = getSpans(text, UnderlineSpan.class);
StyleSpan[] styleSpans = getSpans(text, StyleSpan.class); StyleSpan[] styleSpans = getSpans(text, StyleSpan.class);
assertEquals(1, underlineSpans.length); assertThat(underlineSpans).hasLength(1);
assertEquals(1, styleSpans.length); assertThat(styleSpans).hasLength(1);
assertEquals(23, text.getSpanStart(underlineSpans[0])); assertThat(text.getSpanStart(underlineSpans[0])).isEqualTo(23);
assertEquals(23, text.getSpanStart(styleSpans[0])); assertThat(text.getSpanStart(styleSpans[0])).isEqualTo(23);
assertEquals(43, text.getSpanEnd(underlineSpans[0])); assertThat(text.getSpanEnd(underlineSpans[0])).isEqualTo(43);
assertEquals(43, text.getSpanEnd(styleSpans[0])); assertThat(text.getSpanEnd(styleSpans[0])).isEqualTo(43);
assertEquals(Typeface.ITALIC, styleSpans[0].getStyle()); assertThat(styleSpans[0].getStyle()).isEqualTo(ITALIC);
} }
@Test
public void testParseMalformedNestedElements() throws Exception { public void testParseMalformedNestedElements() throws Exception {
Spanned text = parseCueText("<b><u>An unclosed u tag with <i>italic</u> inside</i></b>"); Spanned text = parseCueText("<b><u>An unclosed u tag with <i>italic</u> inside</i></b>");
assertEquals("An unclosed u tag with italic inside", text.toString()); assertThat(text.toString()).isEqualTo("An unclosed u tag with italic inside");
UnderlineSpan[] underlineSpans = getSpans(text, UnderlineSpan.class); UnderlineSpan[] underlineSpans = getSpans(text, UnderlineSpan.class);
StyleSpan[] styleSpans = getSpans(text, StyleSpan.class); StyleSpan[] styleSpans = getSpans(text, StyleSpan.class);
assertEquals(1, underlineSpans.length); assertThat(underlineSpans).hasLength(1);
assertEquals(2, styleSpans.length); assertThat(styleSpans).hasLength(2);
// all tags applied until matching start tag found // all tags applied until matching start tag found
assertEquals(0, text.getSpanStart(underlineSpans[0])); assertThat(text.getSpanStart(underlineSpans[0])).isEqualTo(0);
assertEquals(29, text.getSpanEnd(underlineSpans[0])); assertThat(text.getSpanEnd(underlineSpans[0])).isEqualTo(29);
if (styleSpans[0].getStyle() == Typeface.BOLD) { if (styleSpans[0].getStyle() == Typeface.BOLD) {
assertEquals(0, text.getSpanStart(styleSpans[0])); assertThat(text.getSpanStart(styleSpans[0])).isEqualTo(0);
assertEquals(23, text.getSpanStart(styleSpans[1])); assertThat(text.getSpanStart(styleSpans[1])).isEqualTo(23);
assertEquals(29, text.getSpanEnd(styleSpans[1])); assertThat(text.getSpanEnd(styleSpans[1])).isEqualTo(29);
assertEquals(36, text.getSpanEnd(styleSpans[0])); assertThat(text.getSpanEnd(styleSpans[0])).isEqualTo(36);
} else { } else {
assertEquals(0, text.getSpanStart(styleSpans[1])); assertThat(text.getSpanStart(styleSpans[1])).isEqualTo(0);
assertEquals(23, text.getSpanStart(styleSpans[0])); assertThat(text.getSpanStart(styleSpans[0])).isEqualTo(23);
assertEquals(29, text.getSpanEnd(styleSpans[0])); assertThat(text.getSpanEnd(styleSpans[0])).isEqualTo(29);
assertEquals(36, text.getSpanEnd(styleSpans[1])); assertThat(text.getSpanEnd(styleSpans[1])).isEqualTo(36);
} }
} }
@Test
public void testParseCloseNonExistingTag() throws Exception { public void testParseCloseNonExistingTag() throws Exception {
Spanned text = parseCueText("blah<b>blah</i>blah</b>blah"); Spanned text = parseCueText("blah<b>blah</i>blah</b>blah");
assertEquals("blahblahblahblah", text.toString()); assertThat(text.toString()).isEqualTo("blahblahblahblah");
StyleSpan[] spans = getSpans(text, StyleSpan.class); StyleSpan[] spans = getSpans(text, StyleSpan.class);
assertEquals(1, spans.length); assertThat(spans).hasLength(1);
assertEquals(Typeface.BOLD, spans[0].getStyle()); assertThat(spans[0].getStyle()).isEqualTo(BOLD);
assertEquals(4, text.getSpanStart(spans[0])); assertThat(text.getSpanStart(spans[0])).isEqualTo(4);
assertEquals(8, text.getSpanEnd(spans[0])); // should be 12 when valid assertThat(text.getSpanEnd(spans[0])).isEqualTo(8); // should be 12 when valid
} }
@Test
public void testParseEmptyTagName() throws Exception { public void testParseEmptyTagName() throws Exception {
Spanned text = parseCueText("An unclosed u tag with <>italic inside"); Spanned text = parseCueText("An unclosed u tag with <>italic inside");
assertEquals("An unclosed u tag with italic inside", text.toString()); assertThat(text.toString()).isEqualTo("An unclosed u tag with italic inside");
} }
@Test
public void testParseEntities() throws Exception { public void testParseEntities() throws Exception {
Spanned text = parseCueText("&amp; &gt; &lt; &nbsp;"); Spanned text = parseCueText("&amp; &gt; &lt; &nbsp;");
assertEquals("& > < ", text.toString()); assertThat(text.toString()).isEqualTo("& > < ");
} }
@Test
public void testParseEntitiesUnsupported() throws Exception { public void testParseEntitiesUnsupported() throws Exception {
Spanned text = parseCueText("&noway; &sure;"); Spanned text = parseCueText("&noway; &sure;");
assertEquals(" ", text.toString()); assertThat(text.toString()).isEqualTo(" ");
} }
@Test
public void testParseEntitiesNotTerminated() throws Exception { public void testParseEntitiesNotTerminated() throws Exception {
Spanned text = parseCueText("&amp here comes text"); Spanned text = parseCueText("&amp here comes text");
assertEquals("& here comes text", text.toString()); assertThat(text.toString()).isEqualTo("& here comes text");
} }
@Test
public void testParseEntitiesNotTerminatedUnsupported() throws Exception { public void testParseEntitiesNotTerminatedUnsupported() throws Exception {
Spanned text = parseCueText("&surenot here comes text"); Spanned text = parseCueText("&surenot here comes text");
assertEquals(" here comes text", text.toString()); assertThat(text.toString()).isEqualTo(" here comes text");
} }
@Test
public void testParseEntitiesNotTerminatedNoSpace() throws Exception { public void testParseEntitiesNotTerminatedNoSpace() throws Exception {
Spanned text = parseCueText("&surenot"); Spanned text = parseCueText("&surenot");
assertEquals("&surenot", text.toString()); assertThat(text.toString()).isEqualTo("&surenot");
} }
@Test
public void testParseVoidTag() throws Exception { public void testParseVoidTag() throws Exception {
Spanned text = parseCueText("here comes<br/> text<br/>"); Spanned text = parseCueText("here comes<br/> text<br/>");
assertEquals("here comes text", text.toString()); assertThat(text.toString()).isEqualTo("here comes text");
} }
@Test
public void testParseMultipleTagsOfSameKind() { public void testParseMultipleTagsOfSameKind() {
Spanned text = parseCueText("blah <b>blah</b> blah <b>foo</b>"); Spanned text = parseCueText("blah <b>blah</b> blah <b>foo</b>");
assertEquals("blah blah blah foo", text.toString()); assertThat(text.toString()).isEqualTo("blah blah blah foo");
StyleSpan[] spans = getSpans(text, StyleSpan.class); StyleSpan[] spans = getSpans(text, StyleSpan.class);
assertEquals(2, spans.length); assertThat(spans).hasLength(2);
assertEquals(5, text.getSpanStart(spans[0])); assertThat(text.getSpanStart(spans[0])).isEqualTo(5);
assertEquals(9, text.getSpanEnd(spans[0])); assertThat(text.getSpanEnd(spans[0])).isEqualTo(9);
assertEquals(15, text.getSpanStart(spans[1])); assertThat(text.getSpanStart(spans[1])).isEqualTo(15);
assertEquals(18, text.getSpanEnd(spans[1])); assertThat(text.getSpanEnd(spans[1])).isEqualTo(18);
assertEquals(Typeface.BOLD, spans[0].getStyle()); assertThat(spans[0].getStyle()).isEqualTo(BOLD);
assertEquals(Typeface.BOLD, spans[1].getStyle()); assertThat(spans[1].getStyle()).isEqualTo(BOLD);
} }
@Test
public void testParseInvalidVoidSlash() { public void testParseInvalidVoidSlash() {
Spanned text = parseCueText("blah <b/.st1.st2 trailing stuff> blah"); Spanned text = parseCueText("blah <b/.st1.st2 trailing stuff> blah");
assertEquals("blah blah", text.toString()); assertThat(text.toString()).isEqualTo("blah blah");
StyleSpan[] spans = getSpans(text, StyleSpan.class); StyleSpan[] spans = getSpans(text, StyleSpan.class);
assertEquals(0, spans.length); assertThat(spans).hasLength(0);
} }
@Test
public void testParseMonkey() throws Exception { public void testParseMonkey() throws Exception {
Spanned text = parseCueText("< u>An unclosed u tag with <<<<< i>italic</u></u></u></u >" Spanned text = parseCueText("< u>An unclosed u tag with <<<<< i>italic</u></u></u></u >"
+ "</i><u><u> inside"); + "</i><u><u> inside");
assertEquals("An unclosed u tag with italic inside", text.toString()); assertThat(text.toString()).isEqualTo("An unclosed u tag with italic inside");
text = parseCueText(">>>>>>>>>An unclosed u tag with <<<<< italic</u></u></u>" text = parseCueText(">>>>>>>>>An unclosed u tag with <<<<< italic</u></u></u>"
+ "</u ></i><u><u> inside"); + "</u ></i><u><u> inside");
assertEquals(">>>>>>>>>An unclosed u tag with inside", text.toString()); assertThat(text.toString()).isEqualTo(">>>>>>>>>An unclosed u tag with inside");
} }
@Test
public void testParseCornerCases() throws Exception { public void testParseCornerCases() throws Exception {
Spanned text = parseCueText(">"); Spanned text = parseCueText(">");
assertEquals(">", text.toString()); assertThat(text.toString()).isEqualTo(">");
text = parseCueText("<"); text = parseCueText("<");
assertEquals("", text.toString()); assertThat(text.toString()).isEmpty();
text = parseCueText("<b.st1.st2 annotation"); text = parseCueText("<b.st1.st2 annotation");
assertEquals("", text.toString()); assertThat(text.toString()).isEmpty();
text = parseCueText("<<<<<<<<<<<<<<<<"); text = parseCueText("<<<<<<<<<<<<<<<<");
assertEquals("", text.toString()); assertThat(text.toString()).isEmpty();
text = parseCueText("<<<<<<>><<<<<<<<<<"); text = parseCueText("<<<<<<>><<<<<<<<<<");
assertEquals(">", text.toString()); assertThat(text.toString()).isEqualTo(">");
text = parseCueText("<>"); text = parseCueText("<>");
assertEquals("", text.toString()); assertThat(text.toString()).isEmpty();
text = parseCueText("&"); text = parseCueText("&");
assertEquals("&", text.toString()); assertThat(text.toString()).isEqualTo("&");
text = parseCueText("&&&&&&&"); text = parseCueText("&&&&&&&");
assertEquals("&&&&&&&", text.toString()); assertThat(text.toString()).isEqualTo("&&&&&&&");
} }
private static Spanned parseCueText(String string) { private static Spanned parseCueText(String string) {

View File

@ -15,17 +15,25 @@
*/ */
package com.google.android.exoplayer2.text.webvtt; package com.google.android.exoplayer2.text.webvtt;
import com.google.android.exoplayer2.C; import static com.google.android.exoplayer2.C.INDEX_UNSET;
import static com.google.common.truth.Truth.assertThat;
import static java.lang.Long.MAX_VALUE;
import com.google.android.exoplayer2.text.Cue; import com.google.android.exoplayer2.text.Cue;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import junit.framework.TestCase; import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/** /**
* Unit test for {@link WebvttSubtitle}. * Unit test for {@link WebvttSubtitle}.
*/ */
public class WebvttSubtitleTest extends TestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public class WebvttSubtitleTest {
private static final String FIRST_SUBTITLE_STRING = "This is the first subtitle."; private static final String FIRST_SUBTITLE_STRING = "This is the first subtitle.";
private static final String SECOND_SUBTITLE_STRING = "This is the second subtitle."; private static final String SECOND_SUBTITLE_STRING = "This is the second subtitle.";
@ -65,21 +73,25 @@ public class WebvttSubtitleTest extends TestCase {
nestedSubtitle = new WebvttSubtitle(nestedSubtitleCues); nestedSubtitle = new WebvttSubtitle(nestedSubtitleCues);
} }
@Test
public void testEventCount() { public void testEventCount() {
assertEquals(0, emptySubtitle.getEventTimeCount()); assertThat(emptySubtitle.getEventTimeCount()).isEqualTo(0);
assertEquals(4, simpleSubtitle.getEventTimeCount()); assertThat(simpleSubtitle.getEventTimeCount()).isEqualTo(4);
assertEquals(4, overlappingSubtitle.getEventTimeCount()); assertThat(overlappingSubtitle.getEventTimeCount()).isEqualTo(4);
assertEquals(4, nestedSubtitle.getEventTimeCount()); assertThat(nestedSubtitle.getEventTimeCount()).isEqualTo(4);
} }
@Test
public void testSimpleSubtitleEventTimes() { public void testSimpleSubtitleEventTimes() {
testSubtitleEventTimesHelper(simpleSubtitle); testSubtitleEventTimesHelper(simpleSubtitle);
} }
@Test
public void testSimpleSubtitleEventIndices() { public void testSimpleSubtitleEventIndices() {
testSubtitleEventIndicesHelper(simpleSubtitle); testSubtitleEventIndicesHelper(simpleSubtitle);
} }
@Test
public void testSimpleSubtitleText() { public void testSimpleSubtitleText() {
// Test before first subtitle // Test before first subtitle
assertSingleCueEmpty(simpleSubtitle.getCues(0)); assertSingleCueEmpty(simpleSubtitle.getCues(0));
@ -107,14 +119,17 @@ public class WebvttSubtitleTest extends TestCase {
assertSingleCueEmpty(simpleSubtitle.getCues(Long.MAX_VALUE)); assertSingleCueEmpty(simpleSubtitle.getCues(Long.MAX_VALUE));
} }
@Test
public void testOverlappingSubtitleEventTimes() { public void testOverlappingSubtitleEventTimes() {
testSubtitleEventTimesHelper(overlappingSubtitle); testSubtitleEventTimesHelper(overlappingSubtitle);
} }
@Test
public void testOverlappingSubtitleEventIndices() { public void testOverlappingSubtitleEventIndices() {
testSubtitleEventIndicesHelper(overlappingSubtitle); testSubtitleEventIndicesHelper(overlappingSubtitle);
} }
@Test
public void testOverlappingSubtitleText() { public void testOverlappingSubtitleText() {
// Test before first subtitle // Test before first subtitle
assertSingleCueEmpty(overlappingSubtitle.getCues(0)); assertSingleCueEmpty(overlappingSubtitle.getCues(0));
@ -145,14 +160,17 @@ public class WebvttSubtitleTest extends TestCase {
assertSingleCueEmpty(overlappingSubtitle.getCues(Long.MAX_VALUE)); assertSingleCueEmpty(overlappingSubtitle.getCues(Long.MAX_VALUE));
} }
@Test
public void testNestedSubtitleEventTimes() { public void testNestedSubtitleEventTimes() {
testSubtitleEventTimesHelper(nestedSubtitle); testSubtitleEventTimesHelper(nestedSubtitle);
} }
@Test
public void testNestedSubtitleEventIndices() { public void testNestedSubtitleEventIndices() {
testSubtitleEventIndicesHelper(nestedSubtitle); testSubtitleEventIndicesHelper(nestedSubtitle);
} }
@Test
public void testNestedSubtitleText() { public void testNestedSubtitleText() {
// Test before first subtitle // Test before first subtitle
assertSingleCueEmpty(nestedSubtitle.getCues(0)); assertSingleCueEmpty(nestedSubtitle.getCues(0));
@ -181,46 +199,46 @@ public class WebvttSubtitleTest extends TestCase {
} }
private void testSubtitleEventTimesHelper(WebvttSubtitle subtitle) { private void testSubtitleEventTimesHelper(WebvttSubtitle subtitle) {
assertEquals(1000000, subtitle.getEventTime(0)); assertThat(subtitle.getEventTime(0)).isEqualTo(1000000);
assertEquals(2000000, subtitle.getEventTime(1)); assertThat(subtitle.getEventTime(1)).isEqualTo(2000000);
assertEquals(3000000, subtitle.getEventTime(2)); assertThat(subtitle.getEventTime(2)).isEqualTo(3000000);
assertEquals(4000000, subtitle.getEventTime(3)); assertThat(subtitle.getEventTime(3)).isEqualTo(4000000);
} }
private void testSubtitleEventIndicesHelper(WebvttSubtitle subtitle) { private void testSubtitleEventIndicesHelper(WebvttSubtitle subtitle) {
// Test first event // Test first event
assertEquals(0, subtitle.getNextEventTimeIndex(0)); assertThat(subtitle.getNextEventTimeIndex(0)).isEqualTo(0);
assertEquals(0, subtitle.getNextEventTimeIndex(500000)); assertThat(subtitle.getNextEventTimeIndex(500000)).isEqualTo(0);
assertEquals(0, subtitle.getNextEventTimeIndex(999999)); assertThat(subtitle.getNextEventTimeIndex(999999)).isEqualTo(0);
// Test second event // Test second event
assertEquals(1, subtitle.getNextEventTimeIndex(1000000)); assertThat(subtitle.getNextEventTimeIndex(1000000)).isEqualTo(1);
assertEquals(1, subtitle.getNextEventTimeIndex(1500000)); assertThat(subtitle.getNextEventTimeIndex(1500000)).isEqualTo(1);
assertEquals(1, subtitle.getNextEventTimeIndex(1999999)); assertThat(subtitle.getNextEventTimeIndex(1999999)).isEqualTo(1);
// Test third event // Test third event
assertEquals(2, subtitle.getNextEventTimeIndex(2000000)); assertThat(subtitle.getNextEventTimeIndex(2000000)).isEqualTo(2);
assertEquals(2, subtitle.getNextEventTimeIndex(2500000)); assertThat(subtitle.getNextEventTimeIndex(2500000)).isEqualTo(2);
assertEquals(2, subtitle.getNextEventTimeIndex(2999999)); assertThat(subtitle.getNextEventTimeIndex(2999999)).isEqualTo(2);
// Test fourth event // Test fourth event
assertEquals(3, subtitle.getNextEventTimeIndex(3000000)); assertThat(subtitle.getNextEventTimeIndex(3000000)).isEqualTo(3);
assertEquals(3, subtitle.getNextEventTimeIndex(3500000)); assertThat(subtitle.getNextEventTimeIndex(3500000)).isEqualTo(3);
assertEquals(3, subtitle.getNextEventTimeIndex(3999999)); assertThat(subtitle.getNextEventTimeIndex(3999999)).isEqualTo(3);
// Test null event (i.e. look for events after the last event) // Test null event (i.e. look for events after the last event)
assertEquals(C.INDEX_UNSET, subtitle.getNextEventTimeIndex(4000000)); assertThat(subtitle.getNextEventTimeIndex(4000000)).isEqualTo(INDEX_UNSET);
assertEquals(C.INDEX_UNSET, subtitle.getNextEventTimeIndex(4500000)); assertThat(subtitle.getNextEventTimeIndex(4500000)).isEqualTo(INDEX_UNSET);
assertEquals(C.INDEX_UNSET, subtitle.getNextEventTimeIndex(Long.MAX_VALUE)); assertThat(subtitle.getNextEventTimeIndex(MAX_VALUE)).isEqualTo(INDEX_UNSET);
} }
private void assertSingleCueEmpty(List<Cue> cues) { private void assertSingleCueEmpty(List<Cue> cues) {
assertTrue(cues.size() == 0); assertThat(cues).isEmpty();
} }
private void assertSingleCueTextEquals(String expected, List<Cue> cues) { private void assertSingleCueTextEquals(String expected, List<Cue> cues) {
assertTrue(cues.size() == 1); assertThat(cues).hasSize(1);
assertEquals(expected, cues.get(0).text.toString()); assertThat(cues.get(0).text.toString()).isEqualTo(expected);
} }
} }

View File

@ -15,6 +15,8 @@
*/ */
package com.google.android.exoplayer2.trackselection; package com.google.android.exoplayer2.trackselection;
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.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
@ -22,12 +24,17 @@ import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
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 MappingTrackSelector}. * Unit tests for {@link MappingTrackSelector}.
*/ */
public final class MappingTrackSelectorTest extends TestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class MappingTrackSelectorTest {
private static final RendererCapabilities VIDEO_CAPABILITIES = private static final RendererCapabilities VIDEO_CAPABILITIES =
new FakeRendererCapabilities(C.TRACK_TYPE_VIDEO); new FakeRendererCapabilities(C.TRACK_TYPE_VIDEO);
@ -54,6 +61,7 @@ public final class MappingTrackSelectorTest extends TestCase {
/** /**
* Tests that the video and audio track groups are mapped onto the correct renderers. * Tests that the video and audio track groups are mapped onto the correct renderers.
*/ */
@Test
public void testMapping() throws ExoPlaybackException { public void testMapping() throws ExoPlaybackException {
FakeMappingTrackSelector trackSelector = new FakeMappingTrackSelector(); FakeMappingTrackSelector trackSelector = new FakeMappingTrackSelector();
trackSelector.selectTracks(RENDERER_CAPABILITIES, TRACK_GROUPS); trackSelector.selectTracks(RENDERER_CAPABILITIES, TRACK_GROUPS);
@ -65,6 +73,7 @@ public final class MappingTrackSelectorTest extends TestCase {
* Tests that the video and audio track groups are mapped onto the correct renderers when the * Tests that the video and audio track groups are mapped onto the correct renderers when the
* renderer ordering is reversed. * renderer ordering is reversed.
*/ */
@Test
public void testMappingReverseOrder() throws ExoPlaybackException { public void testMappingReverseOrder() throws ExoPlaybackException {
FakeMappingTrackSelector trackSelector = new FakeMappingTrackSelector(); FakeMappingTrackSelector trackSelector = new FakeMappingTrackSelector();
RendererCapabilities[] reverseOrderRendererCapabilities = new RendererCapabilities[] { RendererCapabilities[] reverseOrderRendererCapabilities = new RendererCapabilities[] {
@ -78,6 +87,7 @@ public final class MappingTrackSelectorTest extends TestCase {
* Tests video and audio track groups are mapped onto the correct renderers when there are * Tests video and audio track groups are mapped onto the correct renderers when there are
* multiple track groups of the same type. * multiple track groups of the same type.
*/ */
@Test
public void testMappingMulti() throws ExoPlaybackException { public void testMappingMulti() throws ExoPlaybackException {
FakeMappingTrackSelector trackSelector = new FakeMappingTrackSelector(); FakeMappingTrackSelector trackSelector = new FakeMappingTrackSelector();
TrackGroupArray multiTrackGroups = new TrackGroupArray(VIDEO_TRACK_GROUP, AUDIO_TRACK_GROUP, TrackGroupArray multiTrackGroups = new TrackGroupArray(VIDEO_TRACK_GROUP, AUDIO_TRACK_GROUP,
@ -92,46 +102,50 @@ public final class MappingTrackSelectorTest extends TestCase {
* TrackGroupArray[], int[][][])} is propagated correctly to the result of * TrackGroupArray[], int[][][])} is propagated correctly to the result of
* {@link MappingTrackSelector#selectTracks(RendererCapabilities[], TrackGroupArray)}. * {@link MappingTrackSelector#selectTracks(RendererCapabilities[], TrackGroupArray)}.
*/ */
@Test
public void testSelectTracks() throws ExoPlaybackException { public void testSelectTracks() throws ExoPlaybackException {
FakeMappingTrackSelector trackSelector = new FakeMappingTrackSelector(TRACK_SELECTIONS); FakeMappingTrackSelector trackSelector = new FakeMappingTrackSelector(TRACK_SELECTIONS);
TrackSelectorResult result = trackSelector.selectTracks(RENDERER_CAPABILITIES, TRACK_GROUPS); TrackSelectorResult result = trackSelector.selectTracks(RENDERER_CAPABILITIES, TRACK_GROUPS);
assertEquals(TRACK_SELECTIONS[0], result.selections.get(0)); assertThat(result.selections.get(0)).isEqualTo(TRACK_SELECTIONS[0]);
assertEquals(TRACK_SELECTIONS[1], result.selections.get(1)); assertThat(result.selections.get(1)).isEqualTo(TRACK_SELECTIONS[1]);
} }
/** /**
* Tests that a null override clears a track selection. * Tests that a null override clears a track selection.
*/ */
@Test
public void testSelectTracksWithNullOverride() throws ExoPlaybackException { public void testSelectTracksWithNullOverride() throws ExoPlaybackException {
FakeMappingTrackSelector trackSelector = new FakeMappingTrackSelector(TRACK_SELECTIONS); FakeMappingTrackSelector trackSelector = new FakeMappingTrackSelector(TRACK_SELECTIONS);
trackSelector.setSelectionOverride(0, new TrackGroupArray(VIDEO_TRACK_GROUP), null); trackSelector.setSelectionOverride(0, new TrackGroupArray(VIDEO_TRACK_GROUP), null);
TrackSelectorResult result = trackSelector.selectTracks(RENDERER_CAPABILITIES, TRACK_GROUPS); TrackSelectorResult result = trackSelector.selectTracks(RENDERER_CAPABILITIES, TRACK_GROUPS);
assertNull(result.selections.get(0)); assertThat(result.selections.get(0)).isNull();
assertEquals(TRACK_SELECTIONS[1], result.selections.get(1)); assertThat(result.selections.get(1)).isEqualTo(TRACK_SELECTIONS[1]);
} }
/** /**
* Tests that a null override can be cleared. * Tests that a null override can be cleared.
*/ */
@Test
public void testSelectTracksWithClearedNullOverride() throws ExoPlaybackException { public void testSelectTracksWithClearedNullOverride() throws ExoPlaybackException {
FakeMappingTrackSelector trackSelector = new FakeMappingTrackSelector(TRACK_SELECTIONS); FakeMappingTrackSelector trackSelector = new FakeMappingTrackSelector(TRACK_SELECTIONS);
trackSelector.setSelectionOverride(0, new TrackGroupArray(VIDEO_TRACK_GROUP), null); trackSelector.setSelectionOverride(0, new TrackGroupArray(VIDEO_TRACK_GROUP), null);
trackSelector.clearSelectionOverride(0, new TrackGroupArray(VIDEO_TRACK_GROUP)); trackSelector.clearSelectionOverride(0, new TrackGroupArray(VIDEO_TRACK_GROUP));
TrackSelectorResult result = trackSelector.selectTracks(RENDERER_CAPABILITIES, TRACK_GROUPS); TrackSelectorResult result = trackSelector.selectTracks(RENDERER_CAPABILITIES, TRACK_GROUPS);
assertEquals(TRACK_SELECTIONS[0], result.selections.get(0)); assertThat(result.selections.get(0)).isEqualTo(TRACK_SELECTIONS[0]);
assertEquals(TRACK_SELECTIONS[1], result.selections.get(1)); assertThat(result.selections.get(1)).isEqualTo(TRACK_SELECTIONS[1]);
} }
/** /**
* Tests that an override is not applied for a different set of available track groups. * Tests that an override is not applied for a different set of available track groups.
*/ */
@Test
public void testSelectTracksWithNullOverrideForDifferentTracks() throws ExoPlaybackException { public void testSelectTracksWithNullOverrideForDifferentTracks() throws ExoPlaybackException {
FakeMappingTrackSelector trackSelector = new FakeMappingTrackSelector(TRACK_SELECTIONS); FakeMappingTrackSelector trackSelector = new FakeMappingTrackSelector(TRACK_SELECTIONS);
trackSelector.setSelectionOverride(0, new TrackGroupArray(VIDEO_TRACK_GROUP), null); trackSelector.setSelectionOverride(0, new TrackGroupArray(VIDEO_TRACK_GROUP), null);
TrackSelectorResult result = trackSelector.selectTracks(RENDERER_CAPABILITIES, TrackSelectorResult result = trackSelector.selectTracks(RENDERER_CAPABILITIES,
new TrackGroupArray(VIDEO_TRACK_GROUP, AUDIO_TRACK_GROUP, VIDEO_TRACK_GROUP)); new TrackGroupArray(VIDEO_TRACK_GROUP, AUDIO_TRACK_GROUP, VIDEO_TRACK_GROUP));
assertEquals(TRACK_SELECTIONS[0], result.selections.get(0)); assertThat(result.selections.get(0)).isEqualTo(TRACK_SELECTIONS[0]);
assertEquals(TRACK_SELECTIONS[1], result.selections.get(1)); assertThat(result.selections.get(1)).isEqualTo(TRACK_SELECTIONS[1]);
} }
/** /**
@ -156,9 +170,9 @@ public final class MappingTrackSelectorTest extends TestCase {
} }
public void assertMappedTrackGroups(int rendererIndex, TrackGroup... expected) { public void assertMappedTrackGroups(int rendererIndex, TrackGroup... expected) {
assertEquals(expected.length, lastRendererTrackGroupArrays[rendererIndex].length); assertThat(lastRendererTrackGroupArrays[rendererIndex].length).isEqualTo(expected.length);
for (int i = 0; i < expected.length; i++) { for (int i = 0; i < expected.length; i++) {
assertEquals(expected[i], lastRendererTrackGroupArrays[rendererIndex].get(i)); assertThat(lastRendererTrackGroupArrays[rendererIndex].get(i)).isEqualTo(expected[i]);
} }
} }

View File

@ -15,26 +15,37 @@
*/ */
package com.google.android.exoplayer2.upstream; package com.google.android.exoplayer2.upstream;
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 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 ByteArrayDataSource}. * Unit tests for {@link ByteArrayDataSource}.
*/ */
public class ByteArrayDataSourceTest extends TestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class ByteArrayDataSourceTest {
private static final byte[] TEST_DATA = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; private static final byte[] TEST_DATA = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
private static final byte[] TEST_DATA_ODD = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; private static final byte[] TEST_DATA_ODD = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
@Test
public void testFullReadSingleBytes() { public void testFullReadSingleBytes() {
readTestData(TEST_DATA, 0, C.LENGTH_UNSET, 1, 0, 1, false); readTestData(TEST_DATA, 0, C.LENGTH_UNSET, 1, 0, 1, false);
} }
@Test
public void testFullReadAllBytes() { public void testFullReadAllBytes() {
readTestData(TEST_DATA, 0, C.LENGTH_UNSET, 100, 0, 100, false); readTestData(TEST_DATA, 0, C.LENGTH_UNSET, 100, 0, 100, false);
} }
@Test
public void testLimitReadSingleBytes() { public void testLimitReadSingleBytes() {
// Limit set to the length of the data. // Limit set to the length of the data.
readTestData(TEST_DATA, 0, TEST_DATA.length, 1, 0, 1, false); readTestData(TEST_DATA, 0, TEST_DATA.length, 1, 0, 1, false);
@ -42,6 +53,7 @@ public class ByteArrayDataSourceTest extends TestCase {
readTestData(TEST_DATA, 0, 6, 1, 0, 1, false); readTestData(TEST_DATA, 0, 6, 1, 0, 1, false);
} }
@Test
public void testFullReadTwoBytes() { public void testFullReadTwoBytes() {
// Try with the total data length an exact multiple of the size of each individual read. // Try with the total data length an exact multiple of the size of each individual read.
readTestData(TEST_DATA, 0, C.LENGTH_UNSET, 2, 0, 2, false); readTestData(TEST_DATA, 0, C.LENGTH_UNSET, 2, 0, 2, false);
@ -49,6 +61,7 @@ public class ByteArrayDataSourceTest extends TestCase {
readTestData(TEST_DATA_ODD, 0, C.LENGTH_UNSET, 2, 0, 2, false); readTestData(TEST_DATA_ODD, 0, C.LENGTH_UNSET, 2, 0, 2, false);
} }
@Test
public void testLimitReadTwoBytes() { public void testLimitReadTwoBytes() {
// Try with the limit an exact multiple of the size of each individual read. // Try with the limit an exact multiple of the size of each individual read.
readTestData(TEST_DATA, 0, 6, 2, 0, 2, false); readTestData(TEST_DATA, 0, 6, 2, 0, 2, false);
@ -56,6 +69,7 @@ public class ByteArrayDataSourceTest extends TestCase {
readTestData(TEST_DATA, 0, 7, 2, 0, 2, false); readTestData(TEST_DATA, 0, 7, 2, 0, 2, false);
} }
@Test
public void testReadFromValidOffsets() { public void testReadFromValidOffsets() {
// Read from an offset without bound. // Read from an offset without bound.
readTestData(TEST_DATA, 1, C.LENGTH_UNSET, 1, 0, 1, false); readTestData(TEST_DATA, 1, C.LENGTH_UNSET, 1, 0, 1, false);
@ -67,6 +81,7 @@ public class ByteArrayDataSourceTest extends TestCase {
readTestData(TEST_DATA, TEST_DATA.length - 1, 1, 1, 0, 1, false); readTestData(TEST_DATA, TEST_DATA.length - 1, 1, 1, 0, 1, false);
} }
@Test
public void testReadFromInvalidOffsets() { public void testReadFromInvalidOffsets() {
// Read from first invalid offset and check failure without bound. // Read from first invalid offset and check failure without bound.
readTestData(TEST_DATA, TEST_DATA.length, C.LENGTH_UNSET, 1, 0, 1, true); readTestData(TEST_DATA, TEST_DATA.length, C.LENGTH_UNSET, 1, 0, 1, true);
@ -74,6 +89,7 @@ public class ByteArrayDataSourceTest extends TestCase {
readTestData(TEST_DATA, TEST_DATA.length, 1, 1, 0, 1, true); readTestData(TEST_DATA, TEST_DATA.length, 1, 1, 0, 1, true);
} }
@Test
public void testReadWithInvalidLength() { public void testReadWithInvalidLength() {
// Read more data than is available. // Read more data than is available.
readTestData(TEST_DATA, 0, TEST_DATA.length + 1, 1, 0, 1, true); readTestData(TEST_DATA, 0, TEST_DATA.length + 1, 1, 0, 1, true);
@ -102,10 +118,10 @@ public class ByteArrayDataSourceTest extends TestCase {
// Open the source. // Open the source.
long length = dataSource.open(new DataSpec(null, dataOffset, dataLength, null)); long length = dataSource.open(new DataSpec(null, dataOffset, dataLength, null));
opened = true; opened = true;
assertFalse(expectFailOnOpen); assertThat(expectFailOnOpen).isFalse();
// Verify the resolved length is as we expect. // Verify the resolved length is as we expect.
assertEquals(expectedFinalBytesRead, length); assertThat(length).isEqualTo(expectedFinalBytesRead);
byte[] outputBuffer = new byte[outputBufferLength]; byte[] outputBuffer = new byte[outputBufferLength];
int accumulatedBytesRead = 0; int accumulatedBytesRead = 0;
@ -113,26 +129,26 @@ public class ByteArrayDataSourceTest extends TestCase {
// Calculate a valid length for the next read, constraining by the specified output buffer // Calculate a valid length for the next read, constraining by the specified output buffer
// length, write offset and maximum write length input parameters. // length, write offset and maximum write length input parameters.
int requestedReadLength = Math.min(maxReadLength, outputBufferLength - writeOffset); int requestedReadLength = Math.min(maxReadLength, outputBufferLength - writeOffset);
assertTrue(requestedReadLength > 0); assertThat(requestedReadLength).isGreaterThan(0);
int bytesRead = dataSource.read(outputBuffer, writeOffset, requestedReadLength); int bytesRead = dataSource.read(outputBuffer, writeOffset, requestedReadLength);
if (bytesRead != C.RESULT_END_OF_INPUT) { if (bytesRead != C.RESULT_END_OF_INPUT) {
assertTrue(bytesRead > 0); assertThat(bytesRead).isGreaterThan(0);
assertTrue(bytesRead <= requestedReadLength); assertThat(bytesRead).isAtMost(requestedReadLength);
// Check the data read was correct. // Check the data read was correct.
for (int i = 0; i < bytesRead; i++) { for (int i = 0; i < bytesRead; i++) {
assertEquals(testData[dataOffset + accumulatedBytesRead + i], assertThat(outputBuffer[writeOffset + i])
outputBuffer[writeOffset + i]); .isEqualTo(testData[dataOffset + accumulatedBytesRead + i]);
} }
// Check that we haven't read more data than we were expecting. // Check that we haven't read more data than we were expecting.
accumulatedBytesRead += bytesRead; accumulatedBytesRead += bytesRead;
assertTrue(accumulatedBytesRead <= expectedFinalBytesRead); assertThat(accumulatedBytesRead).isAtMost(expectedFinalBytesRead);
// If we haven't read all of the bytes the request should have been satisfied in full. // If we haven't read all of the bytes the request should have been satisfied in full.
assertTrue(accumulatedBytesRead == expectedFinalBytesRead assertThat(accumulatedBytesRead == expectedFinalBytesRead
|| bytesRead == requestedReadLength); || bytesRead == requestedReadLength).isTrue();
} else { } else {
// We're done. Check we read the expected number of bytes. // We're done. Check we read the expected number of bytes.
assertEquals(expectedFinalBytesRead, accumulatedBytesRead); assertThat(accumulatedBytesRead).isEqualTo(expectedFinalBytesRead);
return; return;
} }
} }

View File

@ -15,50 +15,65 @@
*/ */
package com.google.android.exoplayer2.upstream; package com.google.android.exoplayer2.upstream;
import static com.google.android.exoplayer2.C.RESULT_END_OF_INPUT;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import android.net.Uri; import android.net.Uri;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.testutil.TestUtil;
import java.io.IOException; import java.io.IOException;
import junit.framework.TestCase; import java.nio.charset.Charset;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/** /**
* Unit tests for {@link DataSchemeDataSource}. * Unit tests for {@link DataSchemeDataSource}.
*/ */
public final class DataSchemeDataSourceTest extends TestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class DataSchemeDataSourceTest {
private DataSource schemeDataDataSource; private DataSource schemeDataDataSource;
@Override @Before
public void setUp() { public void setUp() {
schemeDataDataSource = new DataSchemeDataSource(); schemeDataDataSource = new DataSchemeDataSource();
} }
@Test
public void testBase64Data() throws IOException { public void testBase64Data() throws IOException {
DataSpec dataSpec = buildDataSpec("data:text/plain;base64,eyJwcm92aWRlciI6IndpZGV2aW5lX3Rlc3QiL" DataSpec dataSpec = buildDataSpec("data:text/plain;base64,eyJwcm92aWRlciI6IndpZGV2aW5lX3Rlc3QiL"
+ "CJjb250ZW50X2lkIjoiTWpBeE5WOTBaV0Z5Y3c9PSIsImtleV9pZHMiOlsiMDAwMDAwMDAwMDAwMDAwMDAwMDAwM" + "CJjb250ZW50X2lkIjoiTWpBeE5WOTBaV0Z5Y3c9PSIsImtleV9pZHMiOlsiMDAwMDAwMDAwMDAwMDAwMDAwMDAwM"
+ "DAwMDAwMDAwMDAiXX0="); + "DAwMDAwMDAwMDAiXX0=");
TestUtil.assertDataSourceContent(schemeDataDataSource, dataSpec, DataSourceAsserts.assertDataSourceContent(schemeDataDataSource, dataSpec,
("{\"provider\":\"widevine_test\",\"content_id\":\"MjAxNV90ZWFycw==\",\"key_ids\":" ("{\"provider\":\"widevine_test\",\"content_id\":\"MjAxNV90ZWFycw==\",\"key_ids\":"
+ "[\"00000000000000000000000000000000\"]}").getBytes()); + "[\"00000000000000000000000000000000\"]}").getBytes(Charset.forName(C.UTF8_NAME)));
} }
@Test
public void testAsciiData() throws IOException { public void testAsciiData() throws IOException {
TestUtil.assertDataSourceContent(schemeDataDataSource, buildDataSpec("data:,A%20brief%20note"), DataSourceAsserts.assertDataSourceContent(schemeDataDataSource,
"A brief note".getBytes()); buildDataSpec("data:,A%20brief%20note"),
"A brief note".getBytes(Charset.forName(C.UTF8_NAME)));
} }
@Test
public void testPartialReads() throws IOException { public void testPartialReads() throws IOException {
byte[] buffer = new byte[18]; byte[] buffer = new byte[18];
DataSpec dataSpec = buildDataSpec("data:,012345678901234567"); DataSpec dataSpec = buildDataSpec("data:,012345678901234567");
assertEquals(18, schemeDataDataSource.open(dataSpec)); assertThat(schemeDataDataSource.open(dataSpec)).isEqualTo(18);
assertEquals(9, schemeDataDataSource.read(buffer, 0, 9)); assertThat(schemeDataDataSource.read(buffer, 0, 9)).isEqualTo(9);
assertEquals(0, schemeDataDataSource.read(buffer, 3, 0)); assertThat(schemeDataDataSource.read(buffer, 3, 0)).isEqualTo(0);
assertEquals(9, schemeDataDataSource.read(buffer, 9, 15)); assertThat(schemeDataDataSource.read(buffer, 9, 15)).isEqualTo(9);
assertEquals(0, schemeDataDataSource.read(buffer, 1, 0)); assertThat(schemeDataDataSource.read(buffer, 1, 0)).isEqualTo(0);
assertEquals(C.RESULT_END_OF_INPUT, schemeDataDataSource.read(buffer, 1, 1)); assertThat(schemeDataDataSource.read(buffer, 1, 1)).isEqualTo(RESULT_END_OF_INPUT);
assertEquals("012345678901234567", new String(buffer, 0, 18)); assertThat(new String(buffer, 0, 18, C.UTF8_NAME)).isEqualTo("012345678901234567");
} }
@Test
public void testIncorrectScheme() { public void testIncorrectScheme() {
try { try {
schemeDataDataSource.open(buildDataSpec("http://www.google.com")); schemeDataDataSource.open(buildDataSpec("http://www.google.com"));
@ -68,6 +83,7 @@ public final class DataSchemeDataSourceTest extends TestCase {
} }
} }
@Test
public void testMalformedData() { public void testMalformedData() {
try { try {
schemeDataDataSource.open(buildDataSpec("data:text/plain;base64,,This%20is%20Content")); schemeDataDataSource.open(buildDataSpec("data:text/plain;base64,,This%20is%20Content"));

View File

@ -0,0 +1,50 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.upstream;
import static com.google.common.truth.Truth.assertThat;
import com.google.android.exoplayer2.testutil.TestUtil;
import java.io.IOException;
/**
* Assertions for data source tests.
*/
/* package */ final class DataSourceAsserts {
/**
* Asserts that data read from a {@link DataSource} matches {@code expected}.
*
* @param dataSource The {@link DataSource} through which to read.
* @param dataSpec The {@link DataSpec} to use when opening the {@link DataSource}.
* @param expectedData The expected data.
* @throws IOException If an error occurs reading fom the {@link DataSource}.
*/
public static void assertDataSourceContent(DataSource dataSource, DataSpec dataSpec,
byte[] expectedData) throws IOException {
try {
long length = dataSource.open(dataSpec);
assertThat(length).isEqualTo(expectedData.length);
byte[] readData = TestUtil.readToEnd(dataSource);
assertThat(readData).isEqualTo(expectedData);
} finally {
dataSource.close();
}
}
private DataSourceAsserts() {}
}

View File

@ -15,75 +15,84 @@
*/ */
package com.google.android.exoplayer2.upstream; package com.google.android.exoplayer2.upstream;
import static com.google.common.truth.Truth.assertThat;
import android.net.Uri; import android.net.Uri;
import android.test.MoreAsserts;
import com.google.android.exoplayer2.testutil.FakeDataSource; import com.google.android.exoplayer2.testutil.FakeDataSource;
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.Arrays; import java.util.Arrays;
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 DataSourceInputStream}. * Unit tests for {@link DataSourceInputStream}.
*/ */
public class DataSourceInputStreamTest extends TestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class DataSourceInputStreamTest {
private static final byte[] TEST_DATA = TestUtil.buildTestData(16); private static final byte[] TEST_DATA = TestUtil.buildTestData(16);
@Test
public void testReadSingleBytes() throws IOException { public void testReadSingleBytes() throws IOException {
DataSourceInputStream inputStream = buildTestInputStream(); DataSourceInputStream inputStream = buildTestInputStream();
// No bytes read yet. // No bytes read yet.
assertEquals(0, inputStream.bytesRead()); assertThat(inputStream.bytesRead()).isEqualTo(0);
// Read bytes. // Read bytes.
for (int i = 0; i < TEST_DATA.length; i++) { for (int i = 0; i < TEST_DATA.length; i++) {
int readByte = inputStream.read(); int readByte = inputStream.read();
assertTrue(0 <= readByte && readByte < 256); assertThat(0 <= readByte && readByte < 256).isTrue();
assertEquals(TEST_DATA[i] & 0xFF, readByte); assertThat(readByte).isEqualTo(TEST_DATA[i] & 0xFF);
assertEquals(i + 1, inputStream.bytesRead()); assertThat(inputStream.bytesRead()).isEqualTo(i + 1);
} }
// Check end of stream. // Check end of stream.
assertEquals(-1, inputStream.read()); assertThat(inputStream.read()).isEqualTo(-1);
assertEquals(TEST_DATA.length, inputStream.bytesRead()); assertThat(inputStream.bytesRead()).isEqualTo(TEST_DATA.length);
// Check close succeeds. // Check close succeeds.
inputStream.close(); inputStream.close();
} }
@Test
public void testRead() throws IOException { public void testRead() throws IOException {
DataSourceInputStream inputStream = buildTestInputStream(); DataSourceInputStream inputStream = buildTestInputStream();
// Read bytes. // Read bytes.
byte[] readBytes = new byte[TEST_DATA.length]; byte[] readBytes = new byte[TEST_DATA.length];
int totalBytesRead = 0; int totalBytesRead = 0;
while (totalBytesRead < TEST_DATA.length) { while (totalBytesRead < TEST_DATA.length) {
long bytesRead = inputStream.read(readBytes, totalBytesRead, int bytesRead = inputStream.read(readBytes, totalBytesRead,
TEST_DATA.length - totalBytesRead); TEST_DATA.length - totalBytesRead);
assertTrue(bytesRead > 0); assertThat(bytesRead).isGreaterThan(0);
totalBytesRead += bytesRead; totalBytesRead += bytesRead;
assertEquals(totalBytesRead, inputStream.bytesRead()); assertThat(inputStream.bytesRead()).isEqualTo(totalBytesRead);
} }
// Check the read data. // Check the read data.
MoreAsserts.assertEquals(TEST_DATA, readBytes); assertThat(readBytes).isEqualTo(TEST_DATA);
// Check end of stream. // Check end of stream.
assertEquals(TEST_DATA.length, inputStream.bytesRead()); assertThat(inputStream.bytesRead()).isEqualTo(TEST_DATA.length);
assertEquals(TEST_DATA.length, totalBytesRead); assertThat(totalBytesRead).isEqualTo(TEST_DATA.length);
assertEquals(-1, inputStream.read()); assertThat(inputStream.read()).isEqualTo(-1);
// Check close succeeds. // Check close succeeds.
inputStream.close(); inputStream.close();
} }
@Test
public void testSkip() throws IOException { public void testSkip() throws IOException {
DataSourceInputStream inputStream = buildTestInputStream(); DataSourceInputStream inputStream = buildTestInputStream();
// Skip bytes. // Skip bytes.
long totalBytesSkipped = 0; long totalBytesSkipped = 0;
while (totalBytesSkipped < TEST_DATA.length) { while (totalBytesSkipped < TEST_DATA.length) {
long bytesSkipped = inputStream.skip(Long.MAX_VALUE); long bytesSkipped = inputStream.skip(Long.MAX_VALUE);
assertTrue(bytesSkipped > 0); assertThat(bytesSkipped > 0).isTrue();
totalBytesSkipped += bytesSkipped; totalBytesSkipped += bytesSkipped;
assertEquals(totalBytesSkipped, inputStream.bytesRead()); assertThat(inputStream.bytesRead()).isEqualTo(totalBytesSkipped);
} }
// Check end of stream. // Check end of stream.
assertEquals(TEST_DATA.length, inputStream.bytesRead()); assertThat(inputStream.bytesRead()).isEqualTo(TEST_DATA.length);
assertEquals(TEST_DATA.length, totalBytesSkipped); assertThat(totalBytesSkipped).isEqualTo(TEST_DATA.length);
assertEquals(-1, inputStream.read()); assertThat(inputStream.read()).isEqualTo(-1);
// Check close succeeds. // Check close succeeds.
inputStream.close(); inputStream.close();
} }

View File

@ -0,0 +1,115 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.upstream.cache;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import android.net.Uri;
import com.google.android.exoplayer2.testutil.FakeDataSet;
import com.google.android.exoplayer2.testutil.FakeDataSet.FakeData;
import com.google.android.exoplayer2.upstream.DataSourceInputStream;
import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.upstream.DummyDataSource;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
/** Assertion methods for {@link com.google.android.exoplayer2.upstream.cache.Cache}. */
/* package */ final class CacheAsserts {
/** Asserts that the cache content is equal to the data in the {@code fakeDataSet}. */
public static void assertCachedData(Cache cache, FakeDataSet fakeDataSet) throws IOException {
ArrayList<FakeData> allData = fakeDataSet.getAllData();
Uri[] uris = new Uri[allData.size()];
for (int i = 0; i < allData.size(); i++) {
uris[i] = allData.get(i).uri;
}
assertCachedData(cache, fakeDataSet, uris);
}
/**
* Asserts that the cache content is equal to the given subset of data in the {@code fakeDataSet}.
*/
public static void assertCachedData(Cache cache, FakeDataSet fakeDataSet, String... uriStrings)
throws IOException {
Uri[] uris = new Uri[uriStrings.length];
for (int i = 0; i < uriStrings.length; i++) {
uris[i] = Uri.parse(uriStrings[i]);
}
assertCachedData(cache, fakeDataSet, uris);
}
/**
* Asserts that the cache content is equal to the given subset of data in the {@code fakeDataSet}.
*/
public static void assertCachedData(Cache cache, FakeDataSet fakeDataSet, Uri... uris)
throws IOException {
int totalLength = 0;
for (Uri uri : uris) {
byte[] data = fakeDataSet.getData(uri).getData();
assertDataCached(cache, uri, data);
totalLength += data.length;
}
assertThat(cache.getCacheSpace()).isEqualTo(totalLength);
}
/** Asserts that the cache contains the given subset of data in the {@code fakeDataSet}. */
public static void assertDataCached(Cache cache, FakeDataSet fakeDataSet, Uri... uris)
throws IOException {
for (Uri uri : uris) {
assertDataCached(cache, uri, fakeDataSet.getData(uri).getData());
}
}
/** Asserts that the cache contains the given data for {@code uriString}. */
public static void assertDataCached(Cache cache, Uri uri, byte[] expected) throws IOException {
CacheDataSource dataSource = new CacheDataSource(cache, DummyDataSource.INSTANCE, 0);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
DataSourceInputStream inputStream = new DataSourceInputStream(dataSource,
new DataSpec(uri, DataSpec.FLAG_ALLOW_CACHING_UNKNOWN_LENGTH));
try {
inputStream.open();
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
// Ignore
} finally {
inputStream.close();
}
assertWithMessage("Cached data doesn't match expected for '" + uri + "'")
.that(outputStream.toByteArray()).isEqualTo(expected);
}
/** Asserts that there is no cache content for the given {@code uriStrings}. */
public static void assertDataNotCached(Cache cache, String... uriStrings) {
for (String uriString : uriStrings) {
assertWithMessage("There is cached data for '" + uriString + "'")
.that(cache.getCachedSpans(CacheUtil.generateKey(Uri.parse(uriString)))).isNull();
}
}
/** Asserts that the cache is empty. */
public static void assertCacheEmpty(Cache cache) {
assertThat(cache.getCacheSpace()).isEqualTo(0);
}
private CacheAsserts() {}
}

View File

@ -15,11 +15,16 @@
*/ */
package com.google.android.exoplayer2.upstream.cache; package com.google.android.exoplayer2.upstream.cache;
import static com.google.android.exoplayer2.testutil.CacheAsserts.assertCacheEmpty; import static android.net.Uri.EMPTY;
import static com.google.android.exoplayer2.C.LENGTH_UNSET;
import static com.google.android.exoplayer2.upstream.cache.CacheAsserts.assertCacheEmpty;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static java.util.Arrays.copyOf;
import static java.util.Arrays.copyOfRange;
import static org.junit.Assert.fail;
import android.net.Uri; import android.net.Uri;
import android.test.InstrumentationTestCase;
import android.test.MoreAsserts;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.testutil.FakeDataSet.FakeData; import com.google.android.exoplayer2.testutil.FakeDataSet.FakeData;
import com.google.android.exoplayer2.testutil.FakeDataSource; import com.google.android.exoplayer2.testutil.FakeDataSource;
@ -28,12 +33,21 @@ import com.google.android.exoplayer2.upstream.FileDataSource;
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.IOException; import java.io.IOException;
import java.util.Arrays; import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
/** /**
* Unit tests for {@link CacheDataSource}. * Unit tests for {@link CacheDataSource}.
*/ */
public class CacheDataSourceTest extends InstrumentationTestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class CacheDataSourceTest {
private static final byte[] TEST_DATA = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; private static final byte[] TEST_DATA = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
private static final int MAX_CACHE_FILE_SIZE = 3; private static final int MAX_CACHE_FILE_SIZE = 3;
@ -43,47 +57,52 @@ public class CacheDataSourceTest extends InstrumentationTestCase {
private File tempFolder; private File tempFolder;
private SimpleCache cache; private SimpleCache cache;
@Override @Before
public void setUp() throws Exception { public void setUp() throws Exception {
super.setUp(); tempFolder = Util.createTempDirectory(RuntimeEnvironment.application, "ExoPlayerTest");
tempFolder = Util.createTempDirectory(getInstrumentation().getContext(), "ExoPlayerTest");
cache = new SimpleCache(tempFolder, new NoOpCacheEvictor()); cache = new SimpleCache(tempFolder, new NoOpCacheEvictor());
} }
@Override @After
public void tearDown() throws Exception { public void tearDown() throws Exception {
Util.recursiveDelete(tempFolder); Util.recursiveDelete(tempFolder);
super.tearDown();
} }
@Test
public void testMaxCacheFileSize() throws Exception { public void testMaxCacheFileSize() throws Exception {
CacheDataSource cacheDataSource = createCacheDataSource(false, false); CacheDataSource cacheDataSource = createCacheDataSource(false, false);
assertReadDataContentLength(cacheDataSource, false, false); assertReadDataContentLength(cacheDataSource, false, false);
for (String key : cache.getKeys()) { for (String key : cache.getKeys()) {
for (CacheSpan cacheSpan : cache.getCachedSpans(key)) { for (CacheSpan cacheSpan : cache.getCachedSpans(key)) {
assertTrue(cacheSpan.length <= MAX_CACHE_FILE_SIZE); assertThat(cacheSpan.length <= MAX_CACHE_FILE_SIZE).isTrue();
assertTrue(cacheSpan.file.length() <= MAX_CACHE_FILE_SIZE); assertThat(cacheSpan.file.length() <= MAX_CACHE_FILE_SIZE).isTrue();
} }
} }
} }
@Test
public void testCacheAndRead() throws Exception { public void testCacheAndRead() throws Exception {
assertCacheAndRead(false, false); assertCacheAndRead(false, false);
} }
@Test
public void testCacheAndReadUnboundedRequest() throws Exception { public void testCacheAndReadUnboundedRequest() throws Exception {
assertCacheAndRead(true, false); assertCacheAndRead(true, false);
} }
@Test
public void testCacheAndReadUnknownLength() throws Exception { public void testCacheAndReadUnknownLength() throws Exception {
assertCacheAndRead(false, true); assertCacheAndRead(false, true);
} }
// Disabled test as we don't support caching of definitely unknown length content // Disabled test as we don't support caching of definitely unknown length content
@Ignore
@Test
public void disabledTestCacheAndReadUnboundedRequestUnknownLength() throws Exception { public void disabledTestCacheAndReadUnboundedRequestUnknownLength() throws Exception {
assertCacheAndRead(true, true); assertCacheAndRead(true, true);
} }
@Test
public void testUnsatisfiableRange() throws Exception { public void testUnsatisfiableRange() throws Exception {
// Bounded request but the content length is unknown. This forces all data to be cached but not // Bounded request but the content length is unknown. This forces all data to be cached but not
// the length // the length
@ -104,11 +123,12 @@ public class CacheDataSourceTest extends InstrumentationTestCase {
} }
} }
@Test
public void testContentLengthEdgeCases() throws Exception { public void testContentLengthEdgeCases() throws Exception {
// Read partial at EOS but don't cross it so length is unknown // Read partial at EOS but don't cross it so length is unknown
CacheDataSource cacheDataSource = createCacheDataSource(false, true); CacheDataSource cacheDataSource = createCacheDataSource(false, true);
assertReadData(cacheDataSource, true, TEST_DATA.length - 2, 2); assertReadData(cacheDataSource, true, TEST_DATA.length - 2, 2);
assertEquals(C.LENGTH_UNSET, cache.getContentLength(KEY_1)); assertThat(cache.getContentLength(KEY_1)).isEqualTo(LENGTH_UNSET);
// Now do an unbounded request for whole data. This will cause a bounded request from upstream. // Now do an unbounded request for whole data. This will cause a bounded request from upstream.
// End of data from upstream shouldn't be mixed up with EOS and cause length set wrong. // End of data from upstream shouldn't be mixed up with EOS and cause length set wrong.
@ -116,21 +136,23 @@ public class CacheDataSourceTest extends InstrumentationTestCase {
assertReadDataContentLength(cacheDataSource, true, true); assertReadDataContentLength(cacheDataSource, true, true);
// Now the length set correctly do an unbounded request with offset // Now the length set correctly do an unbounded request with offset
assertEquals(2, cacheDataSource.open(new DataSpec(Uri.EMPTY, TEST_DATA.length - 2, assertThat(cacheDataSource.open(new DataSpec(EMPTY, TEST_DATA.length - 2,
C.LENGTH_UNSET, KEY_1))); LENGTH_UNSET, KEY_1))).isEqualTo(2);
// An unbounded request with offset for not cached content // An unbounded request with offset for not cached content
assertEquals(C.LENGTH_UNSET, cacheDataSource.open(new DataSpec(Uri.EMPTY, TEST_DATA.length - 2, assertThat(cacheDataSource.open(new DataSpec(EMPTY, TEST_DATA.length - 2,
C.LENGTH_UNSET, KEY_2))); LENGTH_UNSET, KEY_2))).isEqualTo(LENGTH_UNSET);
} }
@Test
public void testIgnoreCacheForUnsetLengthRequests() throws Exception { public void testIgnoreCacheForUnsetLengthRequests() throws Exception {
CacheDataSource cacheDataSource = createCacheDataSource(false, true, CacheDataSource cacheDataSource = createCacheDataSource(false, true,
CacheDataSource.FLAG_IGNORE_CACHE_FOR_UNSET_LENGTH_REQUESTS); CacheDataSource.FLAG_IGNORE_CACHE_FOR_UNSET_LENGTH_REQUESTS);
assertReadData(cacheDataSource, true, 0, C.LENGTH_UNSET); assertReadData(cacheDataSource, true, 0, C.LENGTH_UNSET);
MoreAsserts.assertEmpty(cache.getKeys()); assertThat(cache.getKeys()).isEmpty();
} }
@Test
public void testReadOnlyCache() throws Exception { public void testReadOnlyCache() throws Exception {
CacheDataSource cacheDataSource = createCacheDataSource(false, false, 0, null); CacheDataSource cacheDataSource = createCacheDataSource(false, false, 0, null);
assertReadDataContentLength(cacheDataSource, false, false); assertReadDataContentLength(cacheDataSource, false, false);
@ -157,9 +179,9 @@ public class CacheDataSourceTest extends InstrumentationTestCase {
boolean unboundedRequest, boolean unknownLength) throws IOException { boolean unboundedRequest, boolean unknownLength) throws IOException {
int length = unboundedRequest ? C.LENGTH_UNSET : TEST_DATA.length; int length = unboundedRequest ? C.LENGTH_UNSET : TEST_DATA.length;
assertReadData(cacheDataSource, unknownLength, 0, length); assertReadData(cacheDataSource, unknownLength, 0, length);
assertEquals("When the range specified, CacheDataSource doesn't reach EOS so shouldn't cache " assertWithMessage("When the range specified, CacheDataSource doesn't reach EOS so shouldn't "
+ "content length", !unboundedRequest ? C.LENGTH_UNSET : TEST_DATA.length, + "cache content length").that(cache.getContentLength(KEY_1))
cache.getContentLength(KEY_1)); .isEqualTo(!unboundedRequest ? C.LENGTH_UNSET : TEST_DATA.length);
} }
private void assertReadData(CacheDataSource cacheDataSource, boolean unknownLength, int position, private void assertReadData(CacheDataSource cacheDataSource, boolean unknownLength, int position,
@ -168,8 +190,8 @@ public class CacheDataSourceTest extends InstrumentationTestCase {
if (length != C.LENGTH_UNSET) { if (length != C.LENGTH_UNSET) {
testDataLength = Math.min(testDataLength, length); testDataLength = Math.min(testDataLength, length);
} }
assertEquals(unknownLength ? length : testDataLength, assertThat(cacheDataSource.open(new DataSpec(EMPTY, position, length, KEY_1)))
cacheDataSource.open(new DataSpec(Uri.EMPTY, position, length, KEY_1))); .isEqualTo(unknownLength ? length : testDataLength);
byte[] buffer = new byte[100]; byte[] buffer = new byte[100];
int totalBytesRead = 0; int totalBytesRead = 0;
@ -180,9 +202,9 @@ public class CacheDataSourceTest extends InstrumentationTestCase {
} }
totalBytesRead += read; totalBytesRead += read;
} }
assertEquals(testDataLength, totalBytesRead); assertThat(totalBytesRead).isEqualTo(testDataLength);
MoreAsserts.assertEquals(Arrays.copyOfRange(TEST_DATA, position, position + testDataLength), assertThat(copyOf(buffer, totalBytesRead))
Arrays.copyOf(buffer, totalBytesRead)); .isEqualTo(copyOfRange(TEST_DATA, position, position + testDataLength));
cacheDataSource.close(); cacheDataSource.close();
} }

View File

@ -15,10 +15,12 @@
*/ */
package com.google.android.exoplayer2.upstream.cache; package com.google.android.exoplayer2.upstream.cache;
import static com.google.common.truth.Truth.assertThat;
import static java.util.Arrays.copyOf;
import static java.util.Arrays.copyOfRange;
import android.content.Context; import android.content.Context;
import android.net.Uri; import android.net.Uri;
import android.test.AndroidTestCase;
import android.test.MoreAsserts;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.testutil.FakeDataSource; import com.google.android.exoplayer2.testutil.FakeDataSource;
import com.google.android.exoplayer2.testutil.TestUtil; import com.google.android.exoplayer2.testutil.TestUtil;
@ -32,13 +34,19 @@ import com.google.android.exoplayer2.upstream.crypto.AesCipherDataSource;
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.IOException; import java.io.IOException;
import java.util.Arrays;
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;
import org.robolectric.annotation.Config;
/** /**
* Additional tests for {@link CacheDataSource}. * Additional tests for {@link CacheDataSource}.
*/ */
public class CacheDataSourceTest2 extends AndroidTestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class CacheDataSourceTest2 {
private static final String EXO_CACHE_DIR = "exo"; private static final String EXO_CACHE_DIR = "exo";
private static final int EXO_CACHE_MAX_FILESIZE = 128; private static final int EXO_CACHE_MAX_FILESIZE = 128;
@ -64,17 +72,20 @@ public class CacheDataSourceTest2 extends AndroidTestCase {
private static final DataSpec START_OFF_BOUNDARY = new DataSpec(URI, OFFSET_OFF_BOUNDARY, private static final DataSpec START_OFF_BOUNDARY = new DataSpec(URI, OFFSET_OFF_BOUNDARY,
DATA.length - OFFSET_OFF_BOUNDARY, KEY); DATA.length - OFFSET_OFF_BOUNDARY, KEY);
@Test
public void testWithoutEncryption() throws IOException { public void testWithoutEncryption() throws IOException {
testReads(false); testReads(false);
} }
@Test
public void testWithEncryption() throws IOException { public void testWithEncryption() throws IOException {
testReads(true); testReads(true);
} }
private void testReads(boolean useEncryption) throws IOException { private void testReads(boolean useEncryption) throws IOException {
FakeDataSource upstreamSource = buildFakeUpstreamSource(); FakeDataSource upstreamSource = buildFakeUpstreamSource();
CacheDataSource source = buildCacheDataSource(getContext(), upstreamSource, useEncryption); CacheDataSource source =
buildCacheDataSource(RuntimeEnvironment.application, upstreamSource, useEncryption);
// First read, should arrive from upstream. // First read, should arrive from upstream.
testRead(END_ON_BOUNDARY, source); testRead(END_ON_BOUNDARY, source);
assertSingleOpen(upstreamSource, 0, OFFSET_ON_BOUNDARY); assertSingleOpen(upstreamSource, 0, OFFSET_ON_BOUNDARY);
@ -110,8 +121,8 @@ public class CacheDataSourceTest2 extends AndroidTestCase {
int maxBytesToRead = random.nextInt(scratch.length) + 1; int maxBytesToRead = random.nextInt(scratch.length) + 1;
bytesRead = source.read(scratch, 0, maxBytesToRead); bytesRead = source.read(scratch, 0, maxBytesToRead);
if (bytesRead != C.RESULT_END_OF_INPUT) { if (bytesRead != C.RESULT_END_OF_INPUT) {
MoreAsserts.assertEquals(Arrays.copyOfRange(DATA, position, position + bytesRead), assertThat(copyOf(scratch, bytesRead))
Arrays.copyOf(scratch, bytesRead)); .isEqualTo(copyOfRange(DATA, position, position + bytesRead));
position += bytesRead; position += bytesRead;
} }
} }
@ -124,10 +135,10 @@ public class CacheDataSourceTest2 extends AndroidTestCase {
*/ */
private void assertSingleOpen(FakeDataSource upstreamSource, int start, int end) { private void assertSingleOpen(FakeDataSource upstreamSource, int start, int end) {
DataSpec[] openedDataSpecs = upstreamSource.getAndClearOpenedDataSpecs(); DataSpec[] openedDataSpecs = upstreamSource.getAndClearOpenedDataSpecs();
assertEquals(1, openedDataSpecs.length); assertThat(openedDataSpecs).hasLength(1);
assertEquals(start, openedDataSpecs[0].position); assertThat(openedDataSpecs[0].position).isEqualTo(start);
assertEquals(start, openedDataSpecs[0].absoluteStreamPosition); assertThat(openedDataSpecs[0].absoluteStreamPosition).isEqualTo(start);
assertEquals(end - start, openedDataSpecs[0].length); assertThat(openedDataSpecs[0].length).isEqualTo(end - start);
} }
/** /**
@ -135,7 +146,7 @@ public class CacheDataSourceTest2 extends AndroidTestCase {
*/ */
private void assertNoOpen(FakeDataSource upstreamSource) { private void assertNoOpen(FakeDataSource upstreamSource) {
DataSpec[] openedDataSpecs = upstreamSource.getAndClearOpenedDataSpecs(); DataSpec[] openedDataSpecs = upstreamSource.getAndClearOpenedDataSpecs();
assertEquals(0, openedDataSpecs.length); assertThat(openedDataSpecs).hasLength(0);
} }
private static FakeDataSource buildFakeUpstreamSource() { private static FakeDataSource buildFakeUpstreamSource() {
@ -177,7 +188,7 @@ public class CacheDataSourceTest2 extends AndroidTestCase {
} }
} }
// Sanity check that the cache really is empty now. // Sanity check that the cache really is empty now.
assertTrue(cache.getKeys().isEmpty()); assertThat(cache.getKeys().isEmpty()).isTrue();
} }
} }

View File

@ -15,11 +15,17 @@
*/ */
package com.google.android.exoplayer2.upstream.cache; package com.google.android.exoplayer2.upstream.cache;
import static com.google.android.exoplayer2.testutil.CacheAsserts.assertCacheEmpty; import static android.net.Uri.EMPTY;
import static com.google.android.exoplayer2.testutil.CacheAsserts.assertCachedData; import static android.net.Uri.parse;
import static com.google.android.exoplayer2.C.LENGTH_UNSET;
import static com.google.android.exoplayer2.upstream.cache.CacheAsserts.assertCacheEmpty;
import static com.google.android.exoplayer2.upstream.cache.CacheAsserts.assertCachedData;
import static com.google.android.exoplayer2.upstream.cache.CacheUtil.generateKey;
import static com.google.android.exoplayer2.upstream.cache.CacheUtil.getKey;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import android.net.Uri; import android.net.Uri;
import android.test.InstrumentationTestCase;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.testutil.FakeDataSet; import com.google.android.exoplayer2.testutil.FakeDataSet;
import com.google.android.exoplayer2.testutil.FakeDataSource; import com.google.android.exoplayer2.testutil.FakeDataSource;
@ -29,13 +35,23 @@ import com.google.android.exoplayer2.upstream.cache.CacheUtil.CachingCounters;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import java.io.EOFException; import java.io.EOFException;
import java.io.File; import java.io.File;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers; import org.mockito.Answers;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
/** /**
* Tests {@link CacheUtil}. * Tests {@link CacheUtil}.
*/ */
public class CacheUtilTest extends InstrumentationTestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public final class CacheUtilTest {
/** /**
* Abstract fake Cache implementation used by the test. This class must be public so Mockito can * Abstract fake Cache implementation used by the test. This class must be public so Mockito can
@ -78,45 +94,46 @@ public class CacheUtilTest extends InstrumentationTestCase {
private File tempFolder; private File tempFolder;
private SimpleCache cache; private SimpleCache cache;
@Override @Before
public void setUp() throws Exception { public void setUp() throws Exception {
super.setUp(); MockitoAnnotations.initMocks(this);
TestUtil.setUpMockito(this);
mockCache.init(); mockCache.init();
tempFolder = Util.createTempDirectory(getInstrumentation().getContext(), "ExoPlayerTest"); tempFolder = Util.createTempDirectory(RuntimeEnvironment.application, "ExoPlayerTest");
cache = new SimpleCache(tempFolder, new NoOpCacheEvictor()); cache = new SimpleCache(tempFolder, new NoOpCacheEvictor());
} }
@Override @After
public void tearDown() throws Exception { public void tearDown() throws Exception {
Util.recursiveDelete(tempFolder); Util.recursiveDelete(tempFolder);
super.tearDown();
} }
@Test
public void testGenerateKey() throws Exception { public void testGenerateKey() throws Exception {
assertNotNull(CacheUtil.generateKey(Uri.EMPTY)); assertThat(generateKey(EMPTY)).isNotNull();
Uri testUri = Uri.parse("test"); Uri testUri = Uri.parse("test");
String key = CacheUtil.generateKey(testUri); String key = CacheUtil.generateKey(testUri);
assertNotNull(key); assertThat(key).isNotNull();
// Should generate the same key for the same input // Should generate the same key for the same input
assertEquals(key, CacheUtil.generateKey(testUri)); assertThat(generateKey(testUri)).isEqualTo(key);
// Should generate different key for different input // Should generate different key for different input
assertFalse(key.equals(CacheUtil.generateKey(Uri.parse("test2")))); assertThat(key.equals(generateKey(parse("test2")))).isFalse();
} }
@Test
public void testGetKey() throws Exception { public void testGetKey() throws Exception {
Uri testUri = Uri.parse("test"); Uri testUri = Uri.parse("test");
String key = "key"; String key = "key";
// If DataSpec.key is present, returns it // If DataSpec.key is present, returns it
assertEquals(key, CacheUtil.getKey(new DataSpec(testUri, 0, C.LENGTH_UNSET, key))); assertThat(getKey(new DataSpec(testUri, 0, LENGTH_UNSET, key))).isEqualTo(key);
// If not generates a new one using DataSpec.uri // If not generates a new one using DataSpec.uri
assertEquals(CacheUtil.generateKey(testUri), assertThat(getKey(new DataSpec(testUri, 0, LENGTH_UNSET, null)))
CacheUtil.getKey(new DataSpec(testUri, 0, C.LENGTH_UNSET, null))); .isEqualTo(generateKey(testUri));
} }
@Test
public void testGetCachedNoData() throws Exception { public void testGetCachedNoData() throws Exception {
CachingCounters counters = new CachingCounters(); CachingCounters counters = new CachingCounters();
CacheUtil.getCached(new DataSpec(Uri.parse("test")), mockCache, counters); CacheUtil.getCached(new DataSpec(Uri.parse("test")), mockCache, counters);
@ -124,6 +141,7 @@ public class CacheUtilTest extends InstrumentationTestCase {
assertCounters(counters, 0, 0, C.LENGTH_UNSET); assertCounters(counters, 0, 0, C.LENGTH_UNSET);
} }
@Test
public void testGetCachedDataUnknownLength() throws Exception { public void testGetCachedDataUnknownLength() throws Exception {
// Mock there is 100 bytes cached at the beginning // Mock there is 100 bytes cached at the beginning
mockCache.spansAndGaps = new int[] {100}; mockCache.spansAndGaps = new int[] {100};
@ -133,6 +151,7 @@ public class CacheUtilTest extends InstrumentationTestCase {
assertCounters(counters, 100, 0, C.LENGTH_UNSET); assertCounters(counters, 100, 0, C.LENGTH_UNSET);
} }
@Test
public void testGetCachedNoDataKnownLength() throws Exception { public void testGetCachedNoDataKnownLength() throws Exception {
mockCache.contentLength = 1000; mockCache.contentLength = 1000;
CachingCounters counters = new CachingCounters(); CachingCounters counters = new CachingCounters();
@ -141,6 +160,7 @@ public class CacheUtilTest extends InstrumentationTestCase {
assertCounters(counters, 0, 0, 1000); assertCounters(counters, 0, 0, 1000);
} }
@Test
public void testGetCached() throws Exception { public void testGetCached() throws Exception {
mockCache.contentLength = 1000; mockCache.contentLength = 1000;
mockCache.spansAndGaps = new int[] {100, 100, 200}; mockCache.spansAndGaps = new int[] {100, 100, 200};
@ -150,6 +170,7 @@ public class CacheUtilTest extends InstrumentationTestCase {
assertCounters(counters, 300, 0, 1000); assertCounters(counters, 300, 0, 1000);
} }
@Test
public void testCache() throws Exception { public void testCache() throws Exception {
FakeDataSet fakeDataSet = new FakeDataSet().setRandomData("test_data", 100); FakeDataSet fakeDataSet = new FakeDataSet().setRandomData("test_data", 100);
FakeDataSource dataSource = new FakeDataSource(fakeDataSet); FakeDataSource dataSource = new FakeDataSource(fakeDataSet);
@ -161,6 +182,7 @@ public class CacheUtilTest extends InstrumentationTestCase {
assertCachedData(cache, fakeDataSet); assertCachedData(cache, fakeDataSet);
} }
@Test
public void testCacheSetOffsetAndLength() throws Exception { public void testCacheSetOffsetAndLength() throws Exception {
FakeDataSet fakeDataSet = new FakeDataSet().setRandomData("test_data", 100); FakeDataSet fakeDataSet = new FakeDataSet().setRandomData("test_data", 100);
FakeDataSource dataSource = new FakeDataSource(fakeDataSet); FakeDataSource dataSource = new FakeDataSource(fakeDataSet);
@ -178,6 +200,7 @@ public class CacheUtilTest extends InstrumentationTestCase {
assertCachedData(cache, fakeDataSet); assertCachedData(cache, fakeDataSet);
} }
@Test
public void testCacheUnknownLength() throws Exception { public void testCacheUnknownLength() throws Exception {
FakeDataSet fakeDataSet = new FakeDataSet().newData("test_data") FakeDataSet fakeDataSet = new FakeDataSet().newData("test_data")
.setSimulateUnknownLength(true) .setSimulateUnknownLength(true)
@ -192,6 +215,7 @@ public class CacheUtilTest extends InstrumentationTestCase {
assertCachedData(cache, fakeDataSet); assertCachedData(cache, fakeDataSet);
} }
@Test
public void testCacheUnknownLengthPartialCaching() throws Exception { public void testCacheUnknownLengthPartialCaching() throws Exception {
FakeDataSet fakeDataSet = new FakeDataSet().newData("test_data") FakeDataSet fakeDataSet = new FakeDataSet().newData("test_data")
.setSimulateUnknownLength(true) .setSimulateUnknownLength(true)
@ -211,6 +235,7 @@ public class CacheUtilTest extends InstrumentationTestCase {
assertCachedData(cache, fakeDataSet); assertCachedData(cache, fakeDataSet);
} }
@Test
public void testCacheLengthExceedsActualDataLength() throws Exception { public void testCacheLengthExceedsActualDataLength() throws Exception {
FakeDataSet fakeDataSet = new FakeDataSet().setRandomData("test_data", 100); FakeDataSet fakeDataSet = new FakeDataSet().setRandomData("test_data", 100);
FakeDataSource dataSource = new FakeDataSource(fakeDataSet); FakeDataSource dataSource = new FakeDataSource(fakeDataSet);
@ -224,6 +249,7 @@ public class CacheUtilTest extends InstrumentationTestCase {
assertCachedData(cache, fakeDataSet); assertCachedData(cache, fakeDataSet);
} }
@Test
public void testCacheThrowEOFException() throws Exception { public void testCacheThrowEOFException() throws Exception {
FakeDataSet fakeDataSet = new FakeDataSet().setRandomData("test_data", 100); FakeDataSet fakeDataSet = new FakeDataSet().setRandomData("test_data", 100);
FakeDataSource dataSource = new FakeDataSource(fakeDataSet); FakeDataSource dataSource = new FakeDataSource(fakeDataSet);
@ -241,6 +267,7 @@ public class CacheUtilTest extends InstrumentationTestCase {
} }
} }
@Test
public void testCachePolling() throws Exception { public void testCachePolling() throws Exception {
final CachingCounters counters = new CachingCounters(); final CachingCounters counters = new CachingCounters();
FakeDataSet fakeDataSet = new FakeDataSet().newData("test_data") FakeDataSet fakeDataSet = new FakeDataSet().newData("test_data")
@ -267,6 +294,7 @@ public class CacheUtilTest extends InstrumentationTestCase {
assertCachedData(cache, fakeDataSet); assertCachedData(cache, fakeDataSet);
} }
@Test
public void testRemove() throws Exception { public void testRemove() throws Exception {
FakeDataSet fakeDataSet = new FakeDataSet().setRandomData("test_data", 100); FakeDataSet fakeDataSet = new FakeDataSet().setRandomData("test_data", 100);
FakeDataSource dataSource = new FakeDataSource(fakeDataSet); FakeDataSource dataSource = new FakeDataSource(fakeDataSet);
@ -283,9 +311,9 @@ public class CacheUtilTest extends InstrumentationTestCase {
private static void assertCounters(CachingCounters counters, int alreadyCachedBytes, private static void assertCounters(CachingCounters counters, int alreadyCachedBytes,
int newlyCachedBytes, int contentLength) { int newlyCachedBytes, int contentLength) {
assertEquals(alreadyCachedBytes, counters.alreadyCachedBytes); assertThat(counters.alreadyCachedBytes).isEqualTo(alreadyCachedBytes);
assertEquals(newlyCachedBytes, counters.newlyCachedBytes); assertThat(counters.newlyCachedBytes).isEqualTo(newlyCachedBytes);
assertEquals(contentLength, counters.contentLength); assertThat(counters.contentLength).isEqualTo(contentLength);
} }
} }

View File

@ -15,8 +15,10 @@
*/ */
package com.google.android.exoplayer2.upstream.cache; package com.google.android.exoplayer2.upstream.cache;
import android.test.InstrumentationTestCase; import static com.google.android.exoplayer2.C.LENGTH_UNSET;
import android.test.MoreAsserts; import static com.google.android.exoplayer2.util.Util.toByteArray;
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.util.Util; import com.google.android.exoplayer2.util.Util;
import java.io.File; import java.io.File;
@ -26,60 +28,71 @@ import java.io.IOException;
import java.util.NavigableSet; import java.util.NavigableSet;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
/** /**
* Unit tests for {@link SimpleCache}. * Unit tests for {@link SimpleCache}.
*/ */
public class SimpleCacheTest extends InstrumentationTestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public class SimpleCacheTest {
private static final String KEY_1 = "key1"; private static final String KEY_1 = "key1";
private File cacheDir; private File cacheDir;
@Override @Before
protected void setUp() throws Exception { public void setUp() throws Exception {
cacheDir = Util.createTempDirectory(getInstrumentation().getContext(), "ExoPlayerTest"); cacheDir = Util.createTempDirectory(RuntimeEnvironment.application, "ExoPlayerTest");
} }
@Override @After
protected void tearDown() throws Exception { public void tearDown() throws Exception {
Util.recursiveDelete(cacheDir); Util.recursiveDelete(cacheDir);
} }
@Test
public void testCommittingOneFile() throws Exception { public void testCommittingOneFile() throws Exception {
SimpleCache simpleCache = getSimpleCache(); SimpleCache simpleCache = getSimpleCache();
CacheSpan cacheSpan1 = simpleCache.startReadWrite(KEY_1, 0); CacheSpan cacheSpan1 = simpleCache.startReadWrite(KEY_1, 0);
assertFalse(cacheSpan1.isCached); assertThat(cacheSpan1.isCached).isFalse();
assertTrue(cacheSpan1.isOpenEnded()); assertThat(cacheSpan1.isOpenEnded()).isTrue();
assertNull(simpleCache.startReadWriteNonBlocking(KEY_1, 0)); assertThat(simpleCache.startReadWriteNonBlocking(KEY_1, 0)).isNull();
assertEquals(0, simpleCache.getKeys().size()); assertThat(simpleCache.getKeys()).isEmpty();
NavigableSet<CacheSpan> cachedSpans = simpleCache.getCachedSpans(KEY_1); NavigableSet<CacheSpan> cachedSpans = simpleCache.getCachedSpans(KEY_1);
assertTrue(cachedSpans == null || cachedSpans.size() == 0); assertThat(cachedSpans == null || cachedSpans.isEmpty()).isTrue();
assertEquals(0, simpleCache.getCacheSpace()); assertThat(simpleCache.getCacheSpace()).isEqualTo(0);
assertEquals(0, cacheDir.listFiles().length); assertThat(cacheDir.listFiles()).hasLength(0);
addCache(simpleCache, KEY_1, 0, 15); addCache(simpleCache, KEY_1, 0, 15);
Set<String> cachedKeys = simpleCache.getKeys(); Set<String> cachedKeys = simpleCache.getKeys();
assertEquals(1, cachedKeys.size()); assertThat(cachedKeys).hasSize(1);
assertTrue(cachedKeys.contains(KEY_1)); assertThat(cachedKeys.contains(KEY_1)).isTrue();
cachedSpans = simpleCache.getCachedSpans(KEY_1); cachedSpans = simpleCache.getCachedSpans(KEY_1);
assertEquals(1, cachedSpans.size()); assertThat(cachedSpans).hasSize(1);
assertTrue(cachedSpans.contains(cacheSpan1)); assertThat(cachedSpans.contains(cacheSpan1)).isTrue();
assertEquals(15, simpleCache.getCacheSpace()); assertThat(simpleCache.getCacheSpace()).isEqualTo(15);
simpleCache.releaseHoleSpan(cacheSpan1); simpleCache.releaseHoleSpan(cacheSpan1);
CacheSpan cacheSpan2 = simpleCache.startReadWrite(KEY_1, 0); CacheSpan cacheSpan2 = simpleCache.startReadWrite(KEY_1, 0);
assertTrue(cacheSpan2.isCached); assertThat(cacheSpan2.isCached).isTrue();
assertFalse(cacheSpan2.isOpenEnded()); assertThat(cacheSpan2.isOpenEnded()).isFalse();
assertEquals(15, cacheSpan2.length); assertThat(cacheSpan2.length).isEqualTo(15);
assertCachedDataReadCorrect(cacheSpan2); assertCachedDataReadCorrect(cacheSpan2);
} }
@Test
public void testReadCacheWithoutReleasingWriteCacheSpan() throws Exception { public void testReadCacheWithoutReleasingWriteCacheSpan() throws Exception {
SimpleCache simpleCache = getSimpleCache(); SimpleCache simpleCache = getSimpleCache();
@ -90,19 +103,20 @@ public class SimpleCacheTest extends InstrumentationTestCase {
simpleCache.releaseHoleSpan(cacheSpan1); simpleCache.releaseHoleSpan(cacheSpan1);
} }
@Test
public void testSetGetLength() throws Exception { public void testSetGetLength() throws Exception {
SimpleCache simpleCache = getSimpleCache(); SimpleCache simpleCache = getSimpleCache();
assertEquals(C.LENGTH_UNSET, simpleCache.getContentLength(KEY_1)); assertThat(simpleCache.getContentLength(KEY_1)).isEqualTo(LENGTH_UNSET);
simpleCache.setContentLength(KEY_1, 15); simpleCache.setContentLength(KEY_1, 15);
assertEquals(15, simpleCache.getContentLength(KEY_1)); assertThat(simpleCache.getContentLength(KEY_1)).isEqualTo(15);
simpleCache.startReadWrite(KEY_1, 0); simpleCache.startReadWrite(KEY_1, 0);
addCache(simpleCache, KEY_1, 0, 15); addCache(simpleCache, KEY_1, 0, 15);
simpleCache.setContentLength(KEY_1, 150); simpleCache.setContentLength(KEY_1, 150);
assertEquals(150, simpleCache.getContentLength(KEY_1)); assertThat(simpleCache.getContentLength(KEY_1)).isEqualTo(150);
addCache(simpleCache, KEY_1, 140, 10); addCache(simpleCache, KEY_1, 140, 10);
@ -110,19 +124,20 @@ public class SimpleCacheTest extends InstrumentationTestCase {
SimpleCache simpleCache2 = getSimpleCache(); SimpleCache simpleCache2 = getSimpleCache();
Set<String> keys = simpleCache.getKeys(); Set<String> keys = simpleCache.getKeys();
Set<String> keys2 = simpleCache2.getKeys(); Set<String> keys2 = simpleCache2.getKeys();
assertEquals(keys, keys2); assertThat(keys2).isEqualTo(keys);
for (String key : keys) { for (String key : keys) {
assertEquals(simpleCache.getContentLength(key), simpleCache2.getContentLength(key)); assertThat(simpleCache2.getContentLength(key)).isEqualTo(simpleCache.getContentLength(key));
assertEquals(simpleCache.getCachedSpans(key), simpleCache2.getCachedSpans(key)); assertThat(simpleCache2.getCachedSpans(key)).isEqualTo(simpleCache.getCachedSpans(key));
} }
// Removing the last span shouldn't cause the length be change next time cache loaded // Removing the last span shouldn't cause the length be change next time cache loaded
SimpleCacheSpan lastSpan = simpleCache2.startReadWrite(KEY_1, 145); SimpleCacheSpan lastSpan = simpleCache2.startReadWrite(KEY_1, 145);
simpleCache2.removeSpan(lastSpan); simpleCache2.removeSpan(lastSpan);
simpleCache2 = getSimpleCache(); simpleCache2 = getSimpleCache();
assertEquals(150, simpleCache2.getContentLength(KEY_1)); assertThat(simpleCache2.getContentLength(KEY_1)).isEqualTo(150);
} }
@Test
public void testReloadCache() throws Exception { public void testReloadCache() throws Exception {
SimpleCache simpleCache = getSimpleCache(); SimpleCache simpleCache = getSimpleCache();
@ -139,6 +154,7 @@ public class SimpleCacheTest extends InstrumentationTestCase {
assertCachedDataReadCorrect(cacheSpan2); assertCachedDataReadCorrect(cacheSpan2);
} }
@Test
public void testEncryptedIndex() throws Exception { public void testEncryptedIndex() throws Exception {
byte[] key = "Bar12345Bar12345".getBytes(C.UTF8_NAME); // 128 bit key byte[] key = "Bar12345Bar12345".getBytes(C.UTF8_NAME); // 128 bit key
SimpleCache simpleCache = getEncryptedSimpleCache(key); SimpleCache simpleCache = getEncryptedSimpleCache(key);
@ -156,6 +172,7 @@ public class SimpleCacheTest extends InstrumentationTestCase {
assertCachedDataReadCorrect(cacheSpan2); assertCachedDataReadCorrect(cacheSpan2);
} }
@Test
public void testEncryptedIndexWrongKey() throws Exception { public void testEncryptedIndexWrongKey() throws Exception {
byte[] key = "Bar12345Bar12345".getBytes(C.UTF8_NAME); // 128 bit key byte[] key = "Bar12345Bar12345".getBytes(C.UTF8_NAME); // 128 bit key
SimpleCache simpleCache = getEncryptedSimpleCache(key); SimpleCache simpleCache = getEncryptedSimpleCache(key);
@ -170,10 +187,11 @@ public class SimpleCacheTest extends InstrumentationTestCase {
simpleCache = getEncryptedSimpleCache(key2); simpleCache = getEncryptedSimpleCache(key2);
// Cache should be cleared // Cache should be cleared
assertEquals(0, simpleCache.getKeys().size()); assertThat(simpleCache.getKeys()).isEmpty();
assertEquals(0, cacheDir.listFiles().length); assertThat(cacheDir.listFiles()).hasLength(0);
} }
@Test
public void testEncryptedIndexLostKey() throws Exception { public void testEncryptedIndexLostKey() throws Exception {
byte[] key = "Bar12345Bar12345".getBytes(C.UTF8_NAME); // 128 bit key byte[] key = "Bar12345Bar12345".getBytes(C.UTF8_NAME); // 128 bit key
SimpleCache simpleCache = getEncryptedSimpleCache(key); SimpleCache simpleCache = getEncryptedSimpleCache(key);
@ -187,41 +205,42 @@ public class SimpleCacheTest extends InstrumentationTestCase {
simpleCache = getSimpleCache(); simpleCache = getSimpleCache();
// Cache should be cleared // Cache should be cleared
assertEquals(0, simpleCache.getKeys().size()); assertThat(simpleCache.getKeys()).isEmpty();
assertEquals(0, cacheDir.listFiles().length); assertThat(cacheDir.listFiles()).hasLength(0);
} }
@Test
public void testGetCachedBytes() throws Exception { public void testGetCachedBytes() throws Exception {
SimpleCache simpleCache = getSimpleCache(); SimpleCache simpleCache = getSimpleCache();
CacheSpan cacheSpan = simpleCache.startReadWrite(KEY_1, 0); CacheSpan cacheSpan = simpleCache.startReadWrite(KEY_1, 0);
// No cached bytes, returns -'length' // No cached bytes, returns -'length'
assertEquals(-100, simpleCache.getCachedBytes(KEY_1, 0, 100)); assertThat(simpleCache.getCachedBytes(KEY_1, 0, 100)).isEqualTo(-100);
// Position value doesn't affect the return value // Position value doesn't affect the return value
assertEquals(-100, simpleCache.getCachedBytes(KEY_1, 20, 100)); assertThat(simpleCache.getCachedBytes(KEY_1, 20, 100)).isEqualTo(-100);
addCache(simpleCache, KEY_1, 0, 15); addCache(simpleCache, KEY_1, 0, 15);
// Returns the length of a single span // Returns the length of a single span
assertEquals(15, simpleCache.getCachedBytes(KEY_1, 0, 100)); assertThat(simpleCache.getCachedBytes(KEY_1, 0, 100)).isEqualTo(15);
// Value is capped by the 'length' // Value is capped by the 'length'
assertEquals(10, simpleCache.getCachedBytes(KEY_1, 0, 10)); assertThat(simpleCache.getCachedBytes(KEY_1, 0, 10)).isEqualTo(10);
addCache(simpleCache, KEY_1, 15, 35); addCache(simpleCache, KEY_1, 15, 35);
// Returns the length of two adjacent spans // Returns the length of two adjacent spans
assertEquals(50, simpleCache.getCachedBytes(KEY_1, 0, 100)); assertThat(simpleCache.getCachedBytes(KEY_1, 0, 100)).isEqualTo(50);
addCache(simpleCache, KEY_1, 60, 10); addCache(simpleCache, KEY_1, 60, 10);
// Not adjacent span doesn't affect return value // Not adjacent span doesn't affect return value
assertEquals(50, simpleCache.getCachedBytes(KEY_1, 0, 100)); assertThat(simpleCache.getCachedBytes(KEY_1, 0, 100)).isEqualTo(50);
// Returns length of hole up to the next cached span // Returns length of hole up to the next cached span
assertEquals(-5, simpleCache.getCachedBytes(KEY_1, 55, 100)); assertThat(simpleCache.getCachedBytes(KEY_1, 55, 100)).isEqualTo(-5);
simpleCache.releaseHoleSpan(cacheSpan); simpleCache.releaseHoleSpan(cacheSpan);
} }
@ -247,11 +266,11 @@ public class SimpleCacheTest extends InstrumentationTestCase {
} }
private static void assertCachedDataReadCorrect(CacheSpan cacheSpan) throws IOException { private static void assertCachedDataReadCorrect(CacheSpan cacheSpan) throws IOException {
assertTrue(cacheSpan.isCached); assertThat(cacheSpan.isCached).isTrue();
byte[] expected = generateData(cacheSpan.key, (int) cacheSpan.position, (int) cacheSpan.length); byte[] expected = generateData(cacheSpan.key, (int) cacheSpan.position, (int) cacheSpan.length);
FileInputStream inputStream = new FileInputStream(cacheSpan.file); FileInputStream inputStream = new FileInputStream(cacheSpan.file);
try { try {
MoreAsserts.assertEquals(expected, Util.toByteArray(inputStream)); assertThat(toByteArray(inputStream)).isEqualTo(expected);
} finally { } finally {
inputStream.close(); inputStream.close();
} }

View File

@ -15,16 +15,25 @@
*/ */
package com.google.android.exoplayer2.upstream.crypto; package com.google.android.exoplayer2.upstream.crypto;
import static com.google.common.truth.Truth.assertThat;
import com.google.android.exoplayer2.testutil.TestUtil; import com.google.android.exoplayer2.testutil.TestUtil;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import java.util.Random; import java.util.Random;
import javax.crypto.Cipher; import javax.crypto.Cipher;
import junit.framework.TestCase; import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/** /**
* Unit tests for {@link AesFlushingCipher}. * Unit tests for {@link AesFlushingCipher}.
*/ */
public class AesFlushingCipherTest extends TestCase { @RunWith(RobolectricTestRunner.class)
@Config(sdk = Config.TARGET_SDK, manifest = Config.NONE)
public class AesFlushingCipherTest {
private static final int DATA_LENGTH = 65536; private static final int DATA_LENGTH = 65536;
private static final byte[] KEY = Util.getUtf8Bytes("testKey:12345678"); private static final byte[] KEY = Util.getUtf8Bytes("testKey:12345678");
@ -35,26 +44,26 @@ public class AesFlushingCipherTest extends TestCase {
private AesFlushingCipher encryptCipher; private AesFlushingCipher encryptCipher;
private AesFlushingCipher decryptCipher; private AesFlushingCipher decryptCipher;
@Override @Before
protected void setUp() { public void setUp() {
encryptCipher = new AesFlushingCipher(Cipher.ENCRYPT_MODE, KEY, NONCE, START_OFFSET); encryptCipher = new AesFlushingCipher(Cipher.ENCRYPT_MODE, KEY, NONCE, START_OFFSET);
decryptCipher = new AesFlushingCipher(Cipher.DECRYPT_MODE, KEY, NONCE, START_OFFSET); decryptCipher = new AesFlushingCipher(Cipher.DECRYPT_MODE, KEY, NONCE, START_OFFSET);
} }
@Override @After
protected void tearDown() { public void tearDown() {
encryptCipher = null; encryptCipher = null;
decryptCipher = null; decryptCipher = null;
} }
private long getMaxUnchangedBytesAllowedPostEncryption(long length) { private static long getMaxUnchangedBytesAllowedPostEncryption(long length) {
// Assuming that not more than 10% of the resultant bytes should be identical. // Assuming that not more than 10% of the resultant bytes should be identical.
// The value of 10% is arbitrary, ciphers standards do not name a value. // The value of 10% is arbitrary, ciphers standards do not name a value.
return length / 10; return length / 10;
} }
// Count the number of bytes that do not match. // Count the number of bytes that do not match.
private int getDifferingByteCount(byte[] data1, byte[] data2, int startOffset) { private static int getDifferingByteCount(byte[] data1, byte[] data2, int startOffset) {
int count = 0; int count = 0;
for (int i = startOffset; i < data1.length; i++) { for (int i = startOffset; i < data1.length; i++) {
if (data1[i] != data2[i]) { if (data1[i] != data2[i]) {
@ -65,25 +74,28 @@ public class AesFlushingCipherTest extends TestCase {
} }
// Count the number of bytes that do not match. // Count the number of bytes that do not match.
private int getDifferingByteCount(byte[] data1, byte[] data2) { private static int getDifferingByteCount(byte[] data1, byte[] data2) {
return getDifferingByteCount(data1, data2, 0); return getDifferingByteCount(data1, data2, 0);
} }
// Test a single encrypt and decrypt call // Test a single encrypt and decrypt call.
@Test
public void testSingle() { public void testSingle() {
byte[] reference = TestUtil.buildTestData(DATA_LENGTH); byte[] reference = TestUtil.buildTestData(DATA_LENGTH);
byte[] data = reference.clone(); byte[] data = reference.clone();
encryptCipher.updateInPlace(data, 0, data.length); encryptCipher.updateInPlace(data, 0, data.length);
int unchangedByteCount = data.length - getDifferingByteCount(reference, data); int unchangedByteCount = data.length - getDifferingByteCount(reference, data);
assertTrue(unchangedByteCount <= getMaxUnchangedBytesAllowedPostEncryption(data.length)); assertThat(unchangedByteCount <= getMaxUnchangedBytesAllowedPostEncryption(data.length))
.isTrue();
decryptCipher.updateInPlace(data, 0, data.length); decryptCipher.updateInPlace(data, 0, data.length);
int differingByteCount = getDifferingByteCount(reference, data); int differingByteCount = getDifferingByteCount(reference, data);
assertEquals(0, differingByteCount); assertThat(differingByteCount).isEqualTo(0);
} }
// Test several encrypt and decrypt calls, each aligned on a 16 byte block size // Test several encrypt and decrypt calls, each aligned on a 16 byte block size.
@Test
public void testAligned() { public void testAligned() {
byte[] reference = TestUtil.buildTestData(DATA_LENGTH); byte[] reference = TestUtil.buildTestData(DATA_LENGTH);
byte[] data = reference.clone(); byte[] data = reference.clone();
@ -93,28 +105,30 @@ public class AesFlushingCipherTest extends TestCase {
while (offset < data.length) { while (offset < data.length) {
int bytes = (1 + random.nextInt(50)) * 16; int bytes = (1 + random.nextInt(50)) * 16;
bytes = Math.min(bytes, data.length - offset); bytes = Math.min(bytes, data.length - offset);
assertEquals(0, bytes % 16); assertThat(bytes % 16).isEqualTo(0);
encryptCipher.updateInPlace(data, offset, bytes); encryptCipher.updateInPlace(data, offset, bytes);
offset += bytes; offset += bytes;
} }
int unchangedByteCount = data.length - getDifferingByteCount(reference, data); int unchangedByteCount = data.length - getDifferingByteCount(reference, data);
assertTrue(unchangedByteCount <= getMaxUnchangedBytesAllowedPostEncryption(data.length)); assertThat(unchangedByteCount <= getMaxUnchangedBytesAllowedPostEncryption(data.length))
.isTrue();
offset = 0; offset = 0;
while (offset < data.length) { while (offset < data.length) {
int bytes = (1 + random.nextInt(50)) * 16; int bytes = (1 + random.nextInt(50)) * 16;
bytes = Math.min(bytes, data.length - offset); bytes = Math.min(bytes, data.length - offset);
assertEquals(0, bytes % 16); assertThat(bytes % 16).isEqualTo(0);
decryptCipher.updateInPlace(data, offset, bytes); decryptCipher.updateInPlace(data, offset, bytes);
offset += bytes; offset += bytes;
} }
int differingByteCount = getDifferingByteCount(reference, data); int differingByteCount = getDifferingByteCount(reference, data);
assertEquals(0, differingByteCount); assertThat(differingByteCount).isEqualTo(0);
} }
// Test several encrypt and decrypt calls, not aligned on block boundary // Test several encrypt and decrypt calls, not aligned on block boundary.
@Test
public void testUnAligned() { public void testUnAligned() {
byte[] reference = TestUtil.buildTestData(DATA_LENGTH); byte[] reference = TestUtil.buildTestData(DATA_LENGTH);
byte[] data = reference.clone(); byte[] data = reference.clone();
@ -130,7 +144,8 @@ public class AesFlushingCipherTest extends TestCase {
} }
int unchangedByteCount = data.length - getDifferingByteCount(reference, data); int unchangedByteCount = data.length - getDifferingByteCount(reference, data);
assertTrue(unchangedByteCount <= getMaxUnchangedBytesAllowedPostEncryption(data.length)); assertThat(unchangedByteCount <= getMaxUnchangedBytesAllowedPostEncryption(data.length))
.isTrue();
offset = 0; offset = 0;
while (offset < data.length) { while (offset < data.length) {
@ -141,10 +156,11 @@ public class AesFlushingCipherTest extends TestCase {
} }
int differingByteCount = getDifferingByteCount(reference, data); int differingByteCount = getDifferingByteCount(reference, data);
assertEquals(0, differingByteCount); assertThat(differingByteCount).isEqualTo(0);
} }
// Test decryption starting from the middle of an encrypted block // Test decryption starting from the middle of an encrypted block.
@Test
public void testMidJoin() { public void testMidJoin() {
byte[] reference = TestUtil.buildTestData(DATA_LENGTH); byte[] reference = TestUtil.buildTestData(DATA_LENGTH);
byte[] data = reference.clone(); byte[] data = reference.clone();
@ -161,7 +177,8 @@ public class AesFlushingCipherTest extends TestCase {
// Verify // Verify
int unchangedByteCount = data.length - getDifferingByteCount(reference, data); int unchangedByteCount = data.length - getDifferingByteCount(reference, data);
assertTrue(unchangedByteCount <= getMaxUnchangedBytesAllowedPostEncryption(data.length)); assertThat(unchangedByteCount <= getMaxUnchangedBytesAllowedPostEncryption(data.length))
.isTrue();
// Setup decryption from random location // Setup decryption from random location
offset = random.nextInt(4096); offset = random.nextInt(4096);
@ -180,7 +197,7 @@ public class AesFlushingCipherTest extends TestCase {
// Verify // Verify
int differingByteCount = getDifferingByteCount(reference, data, originalOffset); int differingByteCount = getDifferingByteCount(reference, data, originalOffset);
assertEquals(0, differingByteCount); assertThat(differingByteCount).isEqualTo(0);
} }
} }

View File

@ -0,0 +1,38 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.source.dash;
import android.test.InstrumentationTestCase;
import org.mockito.MockitoAnnotations;
/**
* Utility for setting up Mockito for instrumentation tests.
*/
public final class MockitoUtil {
/**
* Sets up Mockito for an instrumentation test.
*/
public static void setUpMockito(InstrumentationTestCase instrumentationTestCase) {
// Workaround for https://code.google.com/p/dexmaker/issues/detail?id=2.
System.setProperty("dexmaker.dexcache",
instrumentationTestCase.getInstrumentation().getTargetContext().getCacheDir().getPath());
MockitoAnnotations.initMocks(instrumentationTestCase);
}
private MockitoUtil() {}
}

View File

@ -27,6 +27,7 @@ import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.offline.DownloadException; import com.google.android.exoplayer2.offline.DownloadException;
import com.google.android.exoplayer2.offline.Downloader.ProgressListener; import com.google.android.exoplayer2.offline.Downloader.ProgressListener;
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper; import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
import com.google.android.exoplayer2.source.dash.MockitoUtil;
import com.google.android.exoplayer2.source.dash.manifest.DashManifest; import com.google.android.exoplayer2.source.dash.manifest.DashManifest;
import com.google.android.exoplayer2.source.dash.manifest.RepresentationKey; import com.google.android.exoplayer2.source.dash.manifest.RepresentationKey;
import com.google.android.exoplayer2.testutil.FakeDataSet; import com.google.android.exoplayer2.testutil.FakeDataSet;
@ -54,7 +55,7 @@ public class DashDownloaderTest extends InstrumentationTestCase {
@Override @Override
public void setUp() throws Exception { public void setUp() throws Exception {
super.setUp(); super.setUp();
TestUtil.setUpMockito(this); MockitoUtil.setUpMockito(this);
tempFolder = Util.createTempDirectory(getInstrumentation().getContext(), "ExoPlayerTest"); tempFolder = Util.createTempDirectory(getInstrumentation().getContext(), "ExoPlayerTest");
cache = new SimpleCache(tempFolder, new NoOpCacheEvictor()); cache = new SimpleCache(tempFolder, new NoOpCacheEvictor());
} }

View File

@ -13,19 +13,17 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.google.android.exoplayer2.extractor.ogg; package com.google.android.exoplayer2.testutil;
import com.google.android.exoplayer2.testutil.FakeExtractorInput;
import com.google.android.exoplayer2.testutil.TestUtil;
/** /**
* Provides ogg/vorbis test data in bytes for unit tests. * Provides ogg/vorbis test data in bytes for unit tests.
*/ */
/* package */ final class TestData { public final class OggTestData {
/* package */ static FakeExtractorInput createInput(byte[] data, boolean simulateUnkownLength) { public static FakeExtractorInput createInput(byte[] data, boolean simulateUnknownLength) {
return new FakeExtractorInput.Builder().setData(data).setSimulateIOErrors(true) return new FakeExtractorInput.Builder().setData(data).setSimulateIOErrors(true)
.setSimulateUnknownLength(simulateUnkownLength).setSimulatePartialReads(true).build(); .setSimulateUnknownLength(simulateUnknownLength).setSimulatePartialReads(true).build();
} }
public static byte[] buildOggHeader(int headerType, long granule, int pageSequenceCounter, public static byte[] buildOggHeader(int headerType, long granule, int pageSequenceCounter,

View File

@ -16,7 +16,6 @@
package com.google.android.exoplayer2.testutil; package com.google.android.exoplayer2.testutil;
import android.app.Instrumentation; import android.app.Instrumentation;
import android.test.InstrumentationTestCase;
import android.test.MoreAsserts; import android.test.MoreAsserts;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Timeline;
@ -33,7 +32,6 @@ import java.io.InputStream;
import java.util.Arrays; import java.util.Arrays;
import java.util.Random; import java.util.Random;
import junit.framework.Assert; import junit.framework.Assert;
import org.mockito.MockitoAnnotations;
/** /**
* Utility methods for tests. * Utility methods for tests.
@ -121,13 +119,6 @@ public class TestUtil {
return joined; return joined;
} }
public static void setUpMockito(InstrumentationTestCase instrumentationTestCase) {
// Workaround for https://code.google.com/p/dexmaker/issues/detail?id=2.
System.setProperty("dexmaker.dexcache",
instrumentationTestCase.getInstrumentation().getTargetContext().getCacheDir().getPath());
MockitoAnnotations.initMocks(instrumentationTestCase);
}
public static byte[] getByteArray(Instrumentation instrumentation, String fileName) public static byte[] getByteArray(Instrumentation instrumentation, String fileName)
throws IOException { throws IOException {
return Util.toByteArray(getInputStream(instrumentation, fileName)); return Util.toByteArray(getInputStream(instrumentation, fileName));