### Question:
IncrementalDataTableScan extends DataTableScan { @Override public TableScan appendsBetween(long newFromSnapshotId, long newToSnapshotId) { validateSnapshotIdsRefinement(newFromSnapshotId, newToSnapshotId); return new IncrementalDataTableScan(tableOps(), table(), schema(), context().fromSnapshotId(newFromSnapshotId).toSnapshotId(newToSnapshotId)); } IncrementalDataTableScan(TableOperations ops, Table table, Schema schema, TableScanContext context); @Override TableScan asOfTime(long timestampMillis); @Override TableScan useSnapshot(long scanSnapshotId); @Override TableScan appendsBetween(long newFromSnapshotId, long newToSnapshotId); @Override TableScan appendsAfter(long newFromSnapshotId); @Override CloseableIterable<FileScanTask> planFiles();  }### Answer:
@Test public void testInvalidScans() { add(table.newAppend(), files("A")); AssertHelpers.assertThrows( "from and to snapshots cannot be the same, since from snapshot is exclusive and not part of the scan", IllegalArgumentException.class, "from and to snapshot ids cannot be the same", () -> appendsBetweenScan(1, 1)); add(table.newAppend(), files("B")); add(table.newAppend(), files("C")); add(table.newAppend(), files("D")); add(table.newAppend(), files("E")); AssertHelpers.assertThrows( "Check refinement api", IllegalArgumentException.class, "from snapshot id 1 not in existing snapshot ids range (2, 4]", () -> table.newScan().appendsBetween(2, 5).appendsBetween(1, 4)); AssertHelpers.assertThrows( "Check refinement api", IllegalArgumentException.class, "to snapshot id 3 not in existing snapshot ids range (1, 2]", () -> table.newScan().appendsBetween(1, 2).appendsBetween(1, 3)); }
@Test public void testIgnoreResiduals() throws IOException { add(table.newAppend(), files("A")); add(table.newAppend(), files("B")); add(table.newAppend(), files("C")); TableScan scan1 = table.newScan() .filter(Expressions.equal("id", 5)) .appendsBetween(1, 3); try (CloseableIterable<CombinedScanTask> tasks = scan1.planTasks()) { Assert.assertTrue("Tasks should not be empty", com.google.common.collect.Iterables.size(tasks) > 0); for (CombinedScanTask combinedScanTask : tasks) { for (FileScanTask fileScanTask : combinedScanTask.files()) { Assert.assertNotEquals("Residuals must be preserved", Expressions.alwaysTrue(), fileScanTask.residual()); } } } TableScan scan2 = table.newScan() .filter(Expressions.equal("id", 5)) .appendsBetween(1, 3) .ignoreResiduals(); try (CloseableIterable<CombinedScanTask> tasks = scan2.planTasks()) { Assert.assertTrue("Tasks should not be empty", com.google.common.collect.Iterables.size(tasks) > 0); for (CombinedScanTask combinedScanTask : tasks) { for (FileScanTask fileScanTask : combinedScanTask.files()) { Assert.assertEquals("Residuals must be ignored", Expressions.alwaysTrue(), fileScanTask.residual()); } } } }