refactor - DBWriter.addQueueItem() : refactor enqueue position calculation

to be a unit-testable component (static inner class)
This commit is contained in:
orionlee 2018-05-18 14:47:37 -07:00
parent 363c3614f8
commit ba27ec6b31
3 changed files with 120 additions and 10 deletions

View File

@ -6,6 +6,7 @@ import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import de.danoeh.antennapod.core.event.DownloadLogEvent;
import de.danoeh.antennapod.core.event.FeedListUpdateEvent;
@ -324,21 +325,21 @@ public class DBWriter {
LongList markAsUnplayedIds = new LongList();
List<QueueEvent> events = new ArrayList<>();
List<FeedItem> updatedItems = new ArrayList<>();
ItemEnqueuePositionCalculator positionCalculator =
new ItemEnqueuePositionCalculator(
new ItemEnqueuePositionCalculator.Options()
.setEnqueueAtFront(UserPreferences.enqueueAtFront()));
for (int i = 0; i < itemIds.length; i++) {
if (!itemListContains(queue, itemIds[i])) {
final FeedItem item = DBReader.getFeedItem(itemIds[i]);
if (item != null) {
// add item to either front ot back of queue
boolean addToFront = UserPreferences.enqueueAtFront();
if (addToFront) {
queue.add(i, item);
events.add(QueueEvent.added(item, i));
} else {
queue.add(item);
events.add(QueueEvent.added(item, queue.size() - 1));
}
int insertPosition = positionCalculator.calcPosition(i, item, queue);
queue.add(insertPosition, item);
events.add(QueueEvent.added(item, insertPosition));
item.addTag(FeedItem.TAG_QUEUE);
updatedItems.add(item);
queueModified = true;
@ -395,6 +396,50 @@ public class DBWriter {
events.add(QueueEvent.sorted(queue));
}
@VisibleForTesting
static class ItemEnqueuePositionCalculator {
public static class Options {
private boolean enqueueAtFront = false;
public boolean isEnqueueAtFront() {
return enqueueAtFront;
}
public Options setEnqueueAtFront(boolean enqueueAtFront) {
this.enqueueAtFront = enqueueAtFront;
return this;
}
}
private final @NonNull Options options;
public ItemEnqueuePositionCalculator(@NonNull Options options) {
this.options = options;
}
/**
*
* @param positionAmongToAdd Typically, the callers has a list of items to be inserted to
* the queue. This parameter indicates the position (0-based) of
* the item among the one to inserted. E.g., it is needed for
* enqueue at front option.
*
* @param item the item to be inserted
* @param curQueue the queue to which the item is to be inserted
* @return the position (0-based) the item should be inserted to the named queu
*/
public int calcPosition(int positionAmongToAdd, FeedItem item, List<FeedItem> curQueue) {
if (options.isEnqueueAtFront()) {
// NOT 0, so that when a list of items are inserted, the items inserted
// keep the same order. Returning 0 will reverse the order
return positionAmongToAdd;
} else {
return curQueue.size();
}
}
}
/**
* Removes all FeedItem objects from the queue.
*/

View File

@ -1,6 +1,6 @@
package de.danoeh.antennapod.core.feed;
class FeedMother {
public class FeedMother {
public static final String IMAGE_URL = "http://example.com/image";
public static Feed anyFeed() {

View File

@ -0,0 +1,65 @@
package de.danoeh.antennapod.core.storage;
import org.junit.Test;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMother;
import de.danoeh.antennapod.core.storage.DBWriter.ItemEnqueuePositionCalculator;
import de.danoeh.antennapod.core.storage.DBWriter.ItemEnqueuePositionCalculator.Options;
import static org.junit.Assert.assertEquals;
public class DBWriterTest {
public static class ItemEnqueuePositionCalculatorTest {
@Test
public void testEnqueueDefault() {
ItemEnqueuePositionCalculator calculator =
new ItemEnqueuePositionCalculator(new Options());
List<FeedItem> curQueue = tQueue();
int posActual1 = calculator.calcPosition(0, tFI(101), curQueue);
assertEquals("case default, i.e., add to the end", curQueue.size(), posActual1);
int posActual2 = calculator.calcPosition(1, tFI(102), curQueue);
assertEquals("case default (2nd item)", curQueue.size(), posActual2);
}
@Test
public void testEnqueueAtFront() {
ItemEnqueuePositionCalculator calculator =
new ItemEnqueuePositionCalculator(new Options()
.setEnqueueAtFront(true));
List<FeedItem> curQueue = tQueue();
int posActual1 = calculator.calcPosition(0, tFI(101), curQueue);
assertEquals("case option enqueue at front", 0, posActual1);
int posActual2 = calculator.calcPosition(1, tFI(102), curQueue);
assertEquals("case option enqueue at front (2nd item)", 1, posActual2);
}
private static List<FeedItem> tQueue() {
return Arrays.asList(tFI(11), tFI(12), tFI(13), tFI(14));
}
private static FeedItem tFI(int id) {
FeedItem item = new FeedItem(0, "Item" + id, "ItemId" + id, "url",
new Date(), FeedItem.PLAYED, FeedMother.anyFeed());
return item;
}
}
}