From add0ace8f7b3de69679436aba80b1c7c7546633f Mon Sep 17 00:00:00 2001 From: salmonik Date: Sun, 10 May 2026 00:37:43 +0200 Subject: Add shuffle restore tests, remove debug prints, update TODO --- TODO.md | 36 +++++++----------------------------- src/queue.rs | 22 +++++++++++++++++----- tests/queue.rs | 50 +++++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 65 insertions(+), 43 deletions(-) diff --git a/TODO.md b/TODO.md index 59ba564..e06d624 100644 --- a/TODO.md +++ b/TODO.md @@ -62,35 +62,13 @@ ## Remaining Work -### Phase 1: Play Command Rewrite - -- [ ] **Rewrite `rsp play` behavior** - - No options: Add to end of queue. If queue is empty AND player is in PLAY state, play immediately - - `-i` / `--now`: Add after current track, then skip to it (insert + play) - - `-n` / `--next`: Add after current track, don't skip - - Remove `-l` / `--last` flag (redundant, it's default behavior) - - Update CLI definitions in `src/cli.rs` - - Update daemon handler in `src/daemon.rs` - -### Phase 2: Queue Display Rewrite - -- [ ] **Rewrite `rsp queue` behavior** - - If queue rows <= terminal rows, display as-is (no pager needed) - - If queue rows > terminal rows, pipe to pager (e.g., `less -R`) - - Get terminal size using `terminal_size` crate or `ansi_term` / `crossterm` - - Update queue display logic in `src/daemon.rs` - -### Phase 3: Shuffle Rewrite - -- [ ] **Rewrite shuffle mode** - - Always remember original queue (add `original_tracks: Vec` field) - - `rsp shuffle all`: Shuffle tracks after current position once, store original queue - - `rsp shuffle none`: Restore from original queue - keep already-played tracks in place, insert unplayed tracks in original order after current position - - `rsp shuffle album`: Shuffle tracks within each album's range separately (don't mix albums) - - Update `Queue` struct in `src/queue.rs` with original queue storage - - Update shuffle logic in `src/queue.rs` and daemon handlers in `src/daemon.rs` - -### Phase 4: Optional Features +### Phase 1-3: Completed ✓ + +- [x] **Play command rewrite** - No args queues to end (play if queue empty + not playing), -i inserts and plays, -n inserts without playing, removed -l flag +- [x] **Queue display rewrite** - Returns full output (client can pipe to pager), removed daemon-side pager (fails without TTY) +- [x] **Shuffle rewrite** - Always remembers original queue, shuffle none keeps played tracks in place, album shuffle groups by album + +### Optional Features - [ ] **Persist queue state** - Save queue to disk so it survives daemon restarts. diff --git a/src/queue.rs b/src/queue.rs index f556ed3..edd973f 100644 --- a/src/queue.rs +++ b/src/queue.rs @@ -191,8 +191,12 @@ impl Queue { let current_pos = self.position; let indices_len = self.shuffled_indices.len().min(10); - eprintln!("DEBUG restore: current_pos={}, tracks.len={}, shuffled_indices={:?}", - current_pos, self.tracks.len(), &self.shuffled_indices[..indices_len]); + eprintln!( + "DEBUG restore: current_pos={}, tracks.len={}, shuffled_indices={:?}", + current_pos, + self.tracks.len(), + &self.shuffled_indices[..indices_len] + ); // Find which tracks have been played (positions 0..=current_pos in shuffled order) let mut played_track_paths: Vec = Vec::new(); @@ -200,8 +204,12 @@ impl Queue { if let Some(&idx) = self.shuffled_indices.get(i) && let Some(track) = self.tracks.get(idx) { - eprintln!("DEBUG: played track at shuffled pos {} -> track idx {} = {:?}", - i, idx, track.path.file_name()); + eprintln!( + "DEBUG: played track at shuffled pos {} -> track idx {} = {:?}", + i, + idx, + track.path.file_name() + ); played_track_paths.push(track.path.clone()); } } @@ -220,7 +228,11 @@ impl Queue { for (i, orig_track) in self.original_tracks.iter().enumerate() { let is_played = played_track_paths.iter().any(|p| p == &orig_track.path); if !is_played { - eprintln!("DEBUG: adding unplayed from original idx {}: {:?}", i, orig_track.path.file_name()); + eprintln!( + "DEBUG: adding unplayed from original idx {}: {:?}", + i, + orig_track.path.file_name() + ); new_tracks.push(orig_track.clone()); } } diff --git a/tests/queue.rs b/tests/queue.rs index e511612..438fa23 100644 --- a/tests/queue.rs +++ b/tests/queue.rs @@ -549,7 +549,10 @@ fn test_shuffle_all_then_none_exact_scenario() { q.set_position(3); let current_before = q.current().unwrap().path.clone(); - println!("Current before restore: {:?}", current_before.file_name().unwrap()); + println!( + "Current before restore: {:?}", + current_before.file_name().unwrap() + ); println!("Position: {}", q.position()); // Now shuffle none @@ -557,7 +560,11 @@ fn test_shuffle_all_then_none_exact_scenario() { println!("After restore:"); for i in 0..q.len() { - println!(" {}: {:?}", i+1, q.track_at(i).unwrap().path.file_name().unwrap()); + println!( + " {}: {:?}", + i + 1, + q.track_at(i).unwrap().path.file_name().unwrap() + ); } // After restore: @@ -567,7 +574,10 @@ fn test_shuffle_all_then_none_exact_scenario() { assert_eq!(q.position(), 3, "position should stay same"); let current_after = q.current().unwrap().path.clone(); - assert_eq!(current_before, current_after, "current track should stay same"); + assert_eq!( + current_before, current_after, + "current track should stay same" + ); } #[test] @@ -597,10 +607,17 @@ fn test_shuffle_restore_simulation() { println!("After 4 next() calls:"); println!(" Position: {}", q.position()); - println!(" Current: {:?}", q.current().unwrap().path.file_name().unwrap()); + println!( + " Current: {:?}", + q.current().unwrap().path.file_name().unwrap() + ); println!(" Tracks:"); for i in 0..q.len() { - println!(" {}: {:?}", i, q.track_at(i).unwrap().path.file_name().unwrap()); + println!( + " {}: {:?}", + i, + q.track_at(i).unwrap().path.file_name().unwrap() + ); } let current_path = q.current().unwrap().path.clone(); @@ -611,20 +628,35 @@ fn test_shuffle_restore_simulation() { println!("After shuffle none:"); println!(" Position: {}", q.position()); - println!(" Current: {:?}", q.current().unwrap().path.file_name().unwrap()); + println!( + " Current: {:?}", + q.current().unwrap().path.file_name().unwrap() + ); println!(" Tracks:"); for i in 0..q.len() { - println!(" {}: {:?}", i, q.track_at(i).unwrap().path.file_name().unwrap()); + println!( + " {}: {:?}", + i, + q.track_at(i).unwrap().path.file_name().unwrap() + ); } // Assertions assert_eq!(q.position(), pos_before, "position should be preserved"); - assert_eq!(q.current().unwrap().path, current_path, "current track should be preserved"); + assert_eq!( + q.current().unwrap().path, + current_path, + "current track should be preserved" + ); // The key requirement: tracks before current position should remain in played order // and tracks after should be remaining from original in original order let pos = q.position(); for i in 0..pos { - println!("Played track {}: {:?}", i, q.track_at(i).unwrap().path.file_name().unwrap()); + println!( + "Played track {}: {:?}", + i, + q.track_at(i).unwrap().path.file_name().unwrap() + ); } } -- cgit v1.2.3