Private
Public Access
Read-ahead keeps the next two tracks on the SD card (one without it) and drops files that are no longer coming up. Trusted roots are cached once read, and a failed read is retried instead of leaving every server untrusted until a restart. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
90 lines
4.2 KiB
Java
90 lines
4.2 KiB
Java
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
import com.minamp.PlayQueue;
|
|
import com.minamp.plex.Item;
|
|
|
|
/** Queue semantics: shuffle keeps the current track first and restores order; repeat; edits. */
|
|
public class QueueTest {
|
|
static int fails;
|
|
|
|
static void check(boolean ok, String what) {
|
|
System.out.println((ok ? "PASS " : "FAIL ") + what);
|
|
if (!ok) fails++;
|
|
}
|
|
|
|
static List<Item> tracks(int n) {
|
|
List<Item> l = new ArrayList<Item>();
|
|
for (int i = 0; i < n; i++) { Item t = new Item(); t.type = Item.TRACK; t.title = "T" + i; t.ratingKey = "" + i; l.add(t); }
|
|
return l;
|
|
}
|
|
|
|
static String order(PlayQueue q) {
|
|
StringBuilder sb = new StringBuilder();
|
|
for (int i = 0; i < q.size(); i++) sb.append(q.at(i).title).append(i == q.index() ? "*" : "").append(' ');
|
|
return sb.toString().trim();
|
|
}
|
|
|
|
static String titles(List<Item> l) {
|
|
StringBuilder sb = new StringBuilder();
|
|
for (int i = 0; i < l.size(); i++) sb.append(i > 0 ? " " : "").append(l.get(i).title);
|
|
return sb.toString();
|
|
}
|
|
|
|
public static void main(String[] a) {
|
|
PlayQueue q = PlayQueue.get();
|
|
q.set(tracks(5), 2, false, "Album");
|
|
check(order(q).equals("T0 T1 T2* T3 T4"), "set from index 2: " + order(q));
|
|
q.setShuffle(true);
|
|
check(q.index() == 0 && q.current().title.equals("T2") && q.size() == 5, "shuffle keeps current first: " + order(q));
|
|
q.setShuffle(false);
|
|
check(order(q).equals("T0 T1 T2* T3 T4"), "unshuffle restores order: " + order(q));
|
|
|
|
check(q.advance(false) && q.current().title.equals("T3"), "advance");
|
|
q.advance(false);
|
|
check(!q.advance(false) && q.current().title.equals("T4"), "end of queue stops (repeat off)");
|
|
q.cycleRepeat(); // all
|
|
check(q.advance(false) && q.current().title.equals("T0"), "repeat all wraps");
|
|
q.cycleRepeat(); // one
|
|
check(q.advance(false) && q.current().title.equals("T0"), "repeat one replays on completion");
|
|
check(q.advance(true) && q.current().title.equals("T1"), "manual skip leaves repeat-one track");
|
|
q.cycleRepeat(); // off
|
|
check(q.back() && q.current().title.equals("T0"), "back");
|
|
check(q.back() && q.current().title.equals("T0"), "back at start stays");
|
|
|
|
List<Item> extra = tracks(2);
|
|
extra.get(0).title = "X0"; extra.get(1).title = "X1";
|
|
q.playNext(extra);
|
|
check(order(q).equals("T0* X0 X1 T1 T2 T3 T4"), "play next inserts after current: " + order(q));
|
|
q.remove(1);
|
|
check(order(q).equals("T0* X1 T1 T2 T3 T4"), "remove: " + order(q));
|
|
q.jump(3);
|
|
q.moveNext(0);
|
|
check(order(q).equals("X1 T1 T2* T0 T3 T4"), "move earlier item to play next: " + order(q));
|
|
q.setShuffle(true);
|
|
q.append(tracks(1));
|
|
q.setShuffle(false);
|
|
check(q.size() == 7 && q.current().title.equals("T2"), "items appended while shuffled survive unshuffle: " + order(q));
|
|
q.clearUpcoming();
|
|
check(q.size() == q.index() + 1 && q.current().title.equals("T2"), "clear upcoming: " + order(q));
|
|
q.set(tracks(10), -1, true, "Radio");
|
|
check(q.size() == 10 && q.index() == 0 && q.shuffle(), "shuffle play from random start");
|
|
q.clear();
|
|
check(q.current() == null && q.size() == 0, "clear");
|
|
// read-ahead window: the next two tracks, wrapping only with repeat all, never the current one
|
|
q.set(tracks(4), 1, false, "Ahead");
|
|
check(titles(q.peekAhead(2)).equals("T2 T3"), "peekAhead 2 from T1: " + titles(q.peekAhead(2)));
|
|
q.advance(false); q.advance(false);
|
|
check(titles(q.peekAhead(2)).equals(""), "peekAhead at the end, repeat off: empty");
|
|
q.cycleRepeat(); // all
|
|
check(titles(q.peekAhead(2)).equals("T0 T1"), "peekAhead wraps with repeat all: " + titles(q.peekAhead(2)));
|
|
q.cycleRepeat(); q.cycleRepeat(); // off
|
|
q.set(tracks(2), 0, false, "Two");
|
|
q.cycleRepeat(); // all
|
|
check(titles(q.peekAhead(2)).equals("T1"), "peekAhead skips the current track on wrap: " + titles(q.peekAhead(2)));
|
|
q.cycleRepeat(); q.cycleRepeat(); // off
|
|
System.out.println(fails == 0 ? "ALL PASSED" : fails + " FAILED");
|
|
System.exit(fails == 0 ? 0 : 1);
|
|
}
|
|
}
|