package htsjdk.tribble.readers; import org.testng.Assert; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.StringReader; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * Tests for streams and readers */ public class ReaderTest { @BeforeClass public void setup() throws IOException { } @AfterClass public void teardown() throws Exception { } @Test public void testMultipleLines() throws IOException { testStream("line 1\nline2\n"); } @Test public void testSingleLine() throws IOException { testStream("line 1\n"); } @Test public void testEmpty() throws IOException { testStream(""); } @Test public void testLotsOfLines() throws IOException { final StringBuilder b = new StringBuilder(); for ( int i = 0; i < 10000; i++ ) { b.append("line " + i + "\n"); } testStream(b.toString()); } @Test public void testMassiveLines() throws IOException { final StringBuilder b = new StringBuilder(); for ( int i = 0; i < 10; i++ ) { for ( int j = 0; j < 1000000; j++) { b.append(i + "." + j); } b.append("\n"); } testStream(b.toString()); } @Test public void testSkip() throws IOException { for ( int skipSizeBase : Arrays.asList(0, 10, 100, 1000, 10000, 1000000)) { for ( int skipSizeAdd = 0; skipSizeAdd < 10; skipSizeAdd ++ ) { final int skipSize = skipSizeBase + skipSizeAdd; final byte[] bytes = new byte[skipSize+2]; Arrays.fill(bytes, 0, skipSize, (byte)0); bytes[skipSize] = 1; bytes[skipSize+1] = 2; final InputStream is = new ByteArrayInputStream(bytes); final PositionalBufferedStream pbs = new PositionalBufferedStream(is); pbs.skip(skipSize); // first value is 1 Assert.assertTrue(! pbs.isDone()); Assert.assertEquals(pbs.getPosition(), skipSize); Assert.assertEquals(pbs.peek(), 1); Assert.assertEquals(pbs.read(), 1); Assert.assertTrue(! pbs.isDone()); Assert.assertEquals(pbs.getPosition(), skipSize + 1); Assert.assertEquals(pbs.peek(), 2); Assert.assertEquals(pbs.read(), 2); Assert.assertTrue(pbs.isDone()); } } } private void testStream(final String s) throws IOException { testStream(s.getBytes()); testLineReader(s); } private void testStream(final byte[] bytes) throws IOException { final InputStream is = new ByteArrayInputStream(bytes); final PositionalBufferedStream pbs = new PositionalBufferedStream(is); int bytePos = 0; while ( ! pbs.isDone() ) { Assert.assertTrue(bytePos < bytes.length); // test position Assert.assertEquals(pbs.getPosition(), bytePos); // test peek final byte atPos = bytes[bytePos]; Assert.assertEquals(toByte(pbs.peek()), atPos); // test position Assert.assertEquals(pbs.getPosition(), bytePos); // test read Assert.assertEquals(toByte(pbs.read()), atPos); bytePos++; // test position Assert.assertEquals(pbs.getPosition(), bytePos); // test repeek if ( bytePos < bytes.length ) { Assert.assertEquals(toByte(pbs.peek()), bytes[bytePos]); // test position Assert.assertEquals(pbs.getPosition(), bytePos); } } Assert.assertEquals(bytePos, bytes.length); pbs.close(); } private void testLineReader(final String lines) throws IOException { // read all of the lines into the final BufferedReader br = new BufferedReader(new StringReader(lines)); final List<String> eachLine = new ArrayList<String>(); while (true) { final String line = br.readLine(); if ( line == null ) break; eachLine.add(line); } final byte[] bytes = lines.getBytes(); final InputStream is = new ByteArrayInputStream(bytes); final PositionalBufferedStream pbs = new PositionalBufferedStream(is); final LineReader alr = new AsciiLineReader(pbs); // AsciiLineReader must be used here because it does not read ahead. int bytePos = 0, linePos = 0; /** * TODO: Requires revision: we're calling readLine() here, but making assumptions about how the underlying input stream operates. * Specifically, these tests assume the underlying stream only advances exactly the required number of characters to find the * newline, which is not true for most buffered readers. */ while ( ! pbs.isDone() ) { Assert.assertTrue(bytePos < bytes.length); // test position Assert.assertEquals(pbs.getPosition(), bytePos); // test read final String readLine = alr.readLine(); Assert.assertEquals(readLine, eachLine.get(linePos)); linePos++; bytePos += readLine.length() + 1; // 1 for the terminator // test position Assert.assertEquals(pbs.getPosition(), bytePos); } Assert.assertEquals(linePos, eachLine.size()); Assert.assertEquals(bytePos, bytes.length); pbs.close(); } private final byte toByte(int i) { return (byte)(i & 0xFF); } }