### Question:
ProgressTrackingOutputStream extends OutputStream { @Override public void write( byte[] b, int off, int len ) throws IOException { actual.write( b, off, len ); progress.add( len ); } ProgressTrackingOutputStream( OutputStream actual, Progress progress ); @Override void write( byte[] b, int off, int len ); @Override void flush(); @Override void close(); @Override void write( int b );  }### Answer:
@Test public void shouldTrackSingleByteWrites() throws IOException { OutputStream actual = mock( OutputStream.class ); ProgressListener progressListener = mock( ProgressListener.class ); ProgressTrackingOutputStream.Progress progress = new ProgressTrackingOutputStream.Progress( progressListener, 0 ); try ( ProgressTrackingOutputStream out = new ProgressTrackingOutputStream( actual, progress ) ) { out.write( 10 ); } progress.done(); verify( progressListener ).add( 1 ); verify( progressListener ).done(); verifyNoMoreInteractions( progressListener ); }
@Test public void shouldTrackByteArrayWrites() throws IOException { OutputStream actual = mock( OutputStream.class ); ProgressListener progressListener = mock( ProgressListener.class ); ProgressTrackingOutputStream.Progress progress = new ProgressTrackingOutputStream.Progress( progressListener, 0 ); int length = 14; try ( ProgressTrackingOutputStream out = new ProgressTrackingOutputStream( actual, progress ) ) { out.write( new byte[length] ); } progress.done(); verify( progressListener ).add( length ); verify( progressListener ).done(); verifyNoMoreInteractions( progressListener ); }
@Test public void shouldTrackOffsetByteArrayWrites() throws IOException { OutputStream actual = mock( OutputStream.class ); ProgressListener progressListener = mock( ProgressListener.class ); ProgressTrackingOutputStream.Progress progress = new ProgressTrackingOutputStream.Progress( progressListener, 0 ); int length = 5; try ( ProgressTrackingOutputStream out = new ProgressTrackingOutputStream( actual, progress ) ) { out.write( new byte[length * 2], 2, length ); } progress.done(); verify( progressListener ).add( length ); verify( progressListener ).done(); verifyNoMoreInteractions( progressListener ); }
@Test public void shouldTrackOffsetAfterRewind() throws IOException { OutputStream actual = mock( OutputStream.class ); ProgressListener progressListener = mock( ProgressListener.class ); ProgressTrackingOutputStream.Progress progress = new ProgressTrackingOutputStream.Progress( progressListener, 0 ); try ( ProgressTrackingOutputStream out = new ProgressTrackingOutputStream( actual, progress ) ) { out.write( new byte[20] ); progress.rewindTo( 15 ); out.write( new byte[3] ); out.write( new byte[9] ); } progress.done(); InOrder inOrder = inOrder( progressListener ); inOrder.verify( progressListener ).add( 20 ); inOrder.verify( progressListener ).add( 7 ); inOrder.verify( progressListener ).done(); verifyNoMoreInteractions( progressListener ); }