diff options
author | ByteHamster <info@bytehamster.com> | 2021-02-16 12:28:58 +0100 |
---|---|---|
committer | ByteHamster <info@bytehamster.com> | 2021-02-16 14:39:49 +0100 |
commit | 3f1c1c4bf5915f73d4339285076dd83e59449943 (patch) | |
tree | 044f9262d874cd59ac90de902e85465bc2cf87b0 /core/src/test | |
parent | 0f692be2d439316aea68aeb7d83db261ebbaa8de (diff) | |
download | AntennaPod-3f1c1c4bf5915f73d4339285076dd83e59449943.zip |
Rewrite chapter parser for testability
Diffstat (limited to 'core/src/test')
-rw-r--r-- | core/src/test/java/de/danoeh/antennapod/core/util/id3reader/ChapterReaderTest.java | 105 | ||||
-rw-r--r-- | core/src/test/java/de/danoeh/antennapod/core/util/id3reader/Id3ReaderTest.java | 92 |
2 files changed, 197 insertions, 0 deletions
diff --git a/core/src/test/java/de/danoeh/antennapod/core/util/id3reader/ChapterReaderTest.java b/core/src/test/java/de/danoeh/antennapod/core/util/id3reader/ChapterReaderTest.java new file mode 100644 index 000000000..34580146e --- /dev/null +++ b/core/src/test/java/de/danoeh/antennapod/core/util/id3reader/ChapterReaderTest.java @@ -0,0 +1,105 @@ +package de.danoeh.antennapod.core.util.id3reader; + +import de.danoeh.antennapod.core.feed.Chapter; +import de.danoeh.antennapod.core.feed.ID3Chapter; +import de.danoeh.antennapod.core.util.id3reader.model.FrameHeader; +import org.apache.commons.io.input.CountingInputStream; +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.IOException; + +import static de.danoeh.antennapod.core.util.id3reader.Id3ReaderTest.concat; +import static de.danoeh.antennapod.core.util.id3reader.Id3ReaderTest.generateFrameHeader; +import static de.danoeh.antennapod.core.util.id3reader.Id3ReaderTest.generateId3Header; +import static org.junit.Assert.assertEquals; + +public class ChapterReaderTest { + private static final byte CHAPTER_WITHOUT_SUBFRAME_START_TIME = 23; + private static final byte[] CHAPTER_WITHOUT_SUBFRAME = { + 'C', 'H', '1', 0, // String ID for mapping to CTOC + 0, 0, 0, CHAPTER_WITHOUT_SUBFRAME_START_TIME, // Start time + 0, 0, 0, 0, // End time + 0, 0, 0, 0, // Start offset + 0, 0, 0, 0 // End offset + }; + + @Test + public void testReadFullTagWithChapter() throws IOException, ID3ReaderException { + byte[] chapter = concat( + generateFrameHeader(ChapterReader.FRAME_ID_CHAPTER, CHAPTER_WITHOUT_SUBFRAME.length), + CHAPTER_WITHOUT_SUBFRAME); + byte[] data = concat( + generateId3Header(chapter.length), + chapter); + CountingInputStream inputStream = new CountingInputStream(new ByteArrayInputStream(data)); + ChapterReader reader = new ChapterReader(inputStream); + reader.readInputStream(); + assertEquals(1, reader.getChapters().size()); + assertEquals(CHAPTER_WITHOUT_SUBFRAME_START_TIME, reader.getChapters().get(0).getStart()); + } + + @Test + public void testReadFullTagWithMultipleChapters() throws IOException, ID3ReaderException { + byte[] chapter = concat( + generateFrameHeader(ChapterReader.FRAME_ID_CHAPTER, CHAPTER_WITHOUT_SUBFRAME.length), + CHAPTER_WITHOUT_SUBFRAME); + byte[] data = concat( + generateId3Header(2 * chapter.length), + chapter, + chapter); + CountingInputStream inputStream = new CountingInputStream(new ByteArrayInputStream(data)); + ChapterReader reader = new ChapterReader(inputStream); + reader.readInputStream(); + assertEquals(2, reader.getChapters().size()); + assertEquals(CHAPTER_WITHOUT_SUBFRAME_START_TIME, reader.getChapters().get(0).getStart()); + assertEquals(CHAPTER_WITHOUT_SUBFRAME_START_TIME, reader.getChapters().get(1).getStart()); + } + + @Test + public void testReadChapterWithoutSubframes() throws IOException, ID3ReaderException { + FrameHeader header = new FrameHeader(ChapterReader.FRAME_ID_CHAPTER, + CHAPTER_WITHOUT_SUBFRAME.length, (short) 0); + CountingInputStream inputStream = new CountingInputStream(new ByteArrayInputStream(CHAPTER_WITHOUT_SUBFRAME)); + Chapter chapter = new ChapterReader(inputStream).readChapter(header); + assertEquals(CHAPTER_WITHOUT_SUBFRAME_START_TIME, chapter.getStart()); + } + + @Test + public void testReadChapterWithTitle() throws IOException, ID3ReaderException { + byte[] title = { + ID3Reader.ENCODING_ISO, + 'H', 'e', 'l', 'l', 'o', // Title + 0 // Null-terminated + }; + byte[] chapterData = concat( + CHAPTER_WITHOUT_SUBFRAME, + generateFrameHeader(ChapterReader.FRAME_ID_TITLE, title.length), + title); + FrameHeader header = new FrameHeader(ChapterReader.FRAME_ID_CHAPTER, chapterData.length, (short) 0); + CountingInputStream inputStream = new CountingInputStream(new ByteArrayInputStream(chapterData)); + ChapterReader reader = new ChapterReader(inputStream); + Chapter chapter = reader.readChapter(header); + assertEquals(CHAPTER_WITHOUT_SUBFRAME_START_TIME, chapter.getStart()); + assertEquals("Hello", chapter.getTitle()); + } + + @Test + public void testReadTitleWithGarbage() throws IOException, ID3ReaderException { + byte[] titleSubframeContent = { + ID3Reader.ENCODING_ISO, + 'A', // Title + 0, // Null-terminated + 42, 42, 42, 42 // Garbage, should be ignored + }; + FrameHeader header = new FrameHeader(ChapterReader.FRAME_ID_TITLE, titleSubframeContent.length, (short) 0); + CountingInputStream inputStream = new CountingInputStream(new ByteArrayInputStream(titleSubframeContent)); + ChapterReader reader = new ChapterReader(inputStream); + Chapter chapter = new ID3Chapter("", 0); + reader.readChapterSubFrame(header, chapter); + assertEquals("A", chapter.getTitle()); + + // Should skip the garbage and point to the next frame + assertEquals(titleSubframeContent.length, reader.getPosition()); + } +} diff --git a/core/src/test/java/de/danoeh/antennapod/core/util/id3reader/Id3ReaderTest.java b/core/src/test/java/de/danoeh/antennapod/core/util/id3reader/Id3ReaderTest.java new file mode 100644 index 000000000..53e338416 --- /dev/null +++ b/core/src/test/java/de/danoeh/antennapod/core/util/id3reader/Id3ReaderTest.java @@ -0,0 +1,92 @@ +package de.danoeh.antennapod.core.util.id3reader; + +import de.danoeh.antennapod.core.util.id3reader.model.FrameHeader; +import de.danoeh.antennapod.core.util.id3reader.model.TagHeader; +import org.apache.commons.io.input.CountingInputStream; +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +public class Id3ReaderTest { + @Test + public void testReadString() throws IOException { + byte[] data = { + ID3Reader.ENCODING_ISO, + 'T', 'e', 's', 't', + 0 // Null-terminated + }; + CountingInputStream inputStream = new CountingInputStream(new ByteArrayInputStream(data)); + String string = new ID3Reader(inputStream).readEncodingAndString(1000); + assertEquals("Test", string); + } + + @Test + public void testReadUtf16WithBom() throws IOException { + byte[] data = { + ID3Reader.ENCODING_UTF16_WITH_BOM, + (byte) 0xff, (byte) 0xfe, // BOM + 'A', 0, 'B', 0, 'C', 0, + 0, 0, // Null-terminated + }; + CountingInputStream inputStream = new CountingInputStream(new ByteArrayInputStream(data)); + String string = new ID3Reader(inputStream).readEncodingAndString(1000); + assertEquals("ABC", string); + } + + @Test + public void testReadTagHeader() throws IOException, ID3ReaderException { + byte[] data = generateId3Header(23); + CountingInputStream inputStream = new CountingInputStream(new ByteArrayInputStream(data)); + TagHeader header = new ID3Reader(inputStream).readTagHeader(); + assertEquals("ID3", header.getId()); + assertEquals(42, header.getVersion()); + assertEquals(23, header.getSize()); + } + + @Test + public void testReadFrameHeader() throws IOException { + byte[] data = generateFrameHeader("CHAP", 42); + CountingInputStream inputStream = new CountingInputStream(new ByteArrayInputStream(data)); + FrameHeader header = new ID3Reader(inputStream).readFrameHeader(); + assertEquals("CHAP", header.getId()); + assertEquals(42, header.getSize()); + } + + public static byte[] generateFrameHeader(String id, int size) { + return concat( + id.getBytes(StandardCharsets.ISO_8859_1), // Frame ID + new byte[] { + (byte) (size >> 24), (byte) (size >> 16), + (byte) (size >> 8), (byte) (size), // Size + 0, 0 // Flags + }); + } + + static byte[] generateId3Header(int size) { + return new byte[] { + 'I', 'D', '3', // Identifier + 0, 42, // Version + 0, // Flags + (byte) (size >> 24), (byte) (size >> 16), + (byte) (size >> 8), (byte) (size), // Size + }; + } + + static byte[] concat(byte[]... arrays) { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + try { + for (byte[] array : arrays) { + outputStream.write(array); + } + } catch (IOException e) { + fail(e.getMessage()); + } + return outputStream.toByteArray(); + } +} |