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()); } }