### Question:
MergingBlockEntryReader implements BlockEntryCursor<KEY,VALUE> { void addSource( BlockEntryCursor<KEY,VALUE> source ) { sources.add( new Source( source ) ); } MergingBlockEntryReader( Layout<KEY,VALUE> layout ); @Override boolean next(); @Override KEY key(); @Override VALUE value(); @Override void close();  }### Answer:
@Test void shouldMergeSingleReader() throws IOException { MergingBlockEntryReader<MutableLong,MutableLong> merger = new MergingBlockEntryReader<>( layout ); List<BlockEntry<MutableLong,MutableLong>> data = someBlockEntries( new HashSet<>() ); merger.addSource( newReader( data ) ); List<BlockEntry<MutableLong,MutableLong>> expected = sortAll( singleton( data ) ); verifyMerged( expected, merger ); }
@Test void shouldMergeMultipleReaders() throws IOException { MergingBlockEntryReader<MutableLong,MutableLong> merger = new MergingBlockEntryReader<>( layout ); List<List<BlockEntry<MutableLong,MutableLong>>> datas = new ArrayList<>(); Set<MutableLong> uniqueKeys = new HashSet<>(); int nbrOfReaders = rnd.nextInt( 10 ) + 1; for ( int i = 0; i < nbrOfReaders; i++ ) { List<BlockEntry<MutableLong,MutableLong>> data = someBlockEntries( uniqueKeys ); datas.add( data ); merger.addSource( newReader( data ) ); } List<BlockEntry<MutableLong,MutableLong>> expected = sortAll( datas ); verifyMerged( expected, merger ); }