package picard.illumina.parser;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;
import static htsjdk.samtools.util.CollectionUtil.makeList;
public class PerTilePerCycleParserTest {
public static final List<Integer> DEFAULT_TILES = makeList(1, 2, 3, 4);
public static final int[] DEFAULT_OUTPUT_LENGTHS = new int[]{10, 5, 5};
public static final int[] CYCLES = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
public static final int MAX_CYCLE = 20;
public static final OutputMapping OUTPUT_MAPPING = new OutputMapping(new ReadStructure("20T"));
private class MockCycledIlluminaData implements IlluminaData {
private final List<String> values;
public MockCycledIlluminaData() {
this.values = new ArrayList<String>();
}
public void addValue(final String value) {
values.add(value);
}
public List<String> getValues() {
return values;
}
}
class MockPerTileCycleParser extends PerTileCycleParser<MockCycledIlluminaData> {
private final int[] expectedOutputLengths;
public MockPerTileCycleParser(final File directory, final int lane, final CycleIlluminaFileMap tilesToCycleFiles, final OutputMapping outputMapping) {
super(directory, lane, tilesToCycleFiles, outputMapping);
expectedOutputLengths = outputMapping.getOutputReadLengths();
this.initialize();
}
@Override
protected CycleFilesParser<MockCycledIlluminaData> makeCycleFileParser(final List<File> files) {
return new CycleFilesParser<MockCycledIlluminaData>() {
int currentCycle = 0;
@Override
public void close() {
}
@Override
public MockCycledIlluminaData next() {
final MockCycledIlluminaData ild = new MockCycledIlluminaData();
if (!hasNext()) {
throw new NoSuchElementException();
}
ild.addValue(str_del(files.get(currentCycle++)));
return ild;
}
@Override
public boolean hasNext() {
return currentCycle < MAX_CYCLE;
}
};
}
@Override
public void initialize() {
seekToTile(currentTile);
}
public Set<IlluminaDataType> supportedTypes() {
return null;
}
@Override
public void close() {
//no-op
}
}
public List<String> getFileNames(final List<Integer> tiles) {
final List<String> fileNames = new ArrayList<String>();
for (final Integer tile : tiles) {
for (int i = 1; i <= MAX_CYCLE; i++) {
fileNames.add(str_del(tile, i));
}
}
return fileNames;
}
public CycleIlluminaFileMap getIlluminaFileMaps(final List<Integer> tiles, final int[] cycles) {
final CycleIlluminaFileMap cycleFileMap = new CycleIlluminaFileMap();
for (final int cycle : cycles) {
final IlluminaFileMap fileMap = new IlluminaFileMap();
for (final Integer tile : tiles) {
fileMap.put(tile, new File(str_del(tile, cycle)));
}
cycleFileMap.put(cycle, fileMap);
}
return cycleFileMap;
}
public static String str_del(final Object... objects) {
String out = objects[0].toString();
for (int i = 1; i < objects.length; i++) {
out += "_" + objects[i];
}
return out;
}
@Test
public void basicIterationTest() {
final List<String> expectedValues = getFileNames(DEFAULT_TILES);
final PerTileCycleParser<MockCycledIlluminaData> parser = makeParser();
int index = 0;
while (parser.hasNext()) {
index = compareValues(parser.next().values, expectedValues, index);
}
Assert.assertEquals(index, expectedValues.size());
}
private int compareValues(final List<String> parserValues, final List<String> expectedValues, int index) {
for (final String parserValue : parserValues) {
Assert.assertTrue(index < expectedValues.size());
Assert.assertEquals(parserValue, expectedValues.get(index), "With index " + index);
++index;
}
return index;
}
public PerTileCycleParser<MockCycledIlluminaData> makeParser() {
final CycleIlluminaFileMap fileMap = getIlluminaFileMaps(DEFAULT_TILES, CYCLES);
return new MockPerTileCycleParser(new File("FakeFile"), 1, fileMap, OUTPUT_MAPPING);
}
@DataProvider(name = "seekingTests")
public Object[][] seekingTests() {
return new Object[][]{
{1, 3, null, null},
{22, 1, null, null},
{38, 2, null, null},
{75, 4, null, null},
{1, 3, 70, 1},
{1, 3, 45, 2},
{12, 2, 59, 4},
{45, 3, 70, 3},
{14, 1, 5, 2}
};
}
@Test(dataProvider = "seekingTests")
public void seekingIterationTest(final Integer seekPos1, final Integer newTile1, final Integer seekPos2, final Integer newTile2) {
final List<String> expectedValues = getFileNames(DEFAULT_TILES);
final PerTileCycleParser<MockCycledIlluminaData> parser = makeParser();
int index = 0;
for (int i = 0; i <= seekPos1; i++) {
Assert.assertTrue(parser.hasNext());
index = compareValues(parser.next().values, expectedValues, index);
}
parser.seekToTile(newTile1);
index = (newTile1 - 1) * MAX_CYCLE;
if (seekPos2 != null) {
for (int i = index; i <= seekPos2; i++) {
Assert.assertTrue(parser.hasNext());
index = compareValues(parser.next().values, expectedValues, index);
}
parser.seekToTile(newTile2);
index = (newTile2 - 1) * MAX_CYCLE;
}
for (int i = index; i < MAX_CYCLE * DEFAULT_TILES.size(); i++) {
Assert.assertTrue(parser.hasNext());
index = compareValues(parser.next().values, expectedValues, index);
}
Assert.assertFalse(parser.hasNext());
}
}