aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/queue.rs93
1 files changed, 93 insertions, 0 deletions
diff --git a/tests/queue.rs b/tests/queue.rs
index 2eaa6f3..d338f2a 100644
--- a/tests/queue.rs
+++ b/tests/queue.rs
@@ -474,6 +474,99 @@ fn test_clear_resets_shuffle_indices() {
474 assert!(q.shuffled_indices().is_empty()); 474 assert!(q.shuffled_indices().is_empty());
475} 475}
476 476
477// ---------- Regression tests ----------
478// These encode invariants the queue must uphold across shuffle transitions.
479// They previously failed and now pin the fixed behavior.
480
481#[test]
482fn test_add_during_shuffle_survives_shuffle_off() {
483 // A track added while Shuffle::All is active must survive turning shuffle
484 // off: `restore_from_original` rebuilds the queue from the live track
485 // list (entries, not paths), so late additions are kept.
486 // (src/queue.rs: add_track 223, restore_from_original 266)
487 let mut q = Queue::new();
488 add_track(&mut q, "/music/a.mp3");
489 add_track(&mut q, "/music/b.mp3");
490 add_track(&mut q, "/music/c.mp3");
491 q.set_shuffle(ShuffleMode::All);
492
493 // User adds a track while shuffle is active (e.g. `rsp play --next`).
494 add_track(&mut q, "/music/d.mp3");
495 assert_eq!(q.len(), 4);
496
497 q.set_shuffle(ShuffleMode::None);
498
499 // d.mp3 must still be in the queue.
500 assert_eq!(
501 q.len(),
502 4,
503 "queue lost a track after shuffle-off; len = {}",
504 q.len()
505 );
506 assert!(
507 q.tracks().iter().any(|t| t.path == PathBuf::from("/music/d.mp3")),
508 "track added during shuffle was dropped when shuffle was turned off"
509 );
510}
511
512#[test]
513fn test_clear_then_shuffle_off_does_not_resurrect_queue() {
514 // A cleared queue must stay empty across a later shuffle-off: `clear()`
515 // wipes tracks/position/shuffled_indices, and `restore_from_original`
516 // must not resurrect entries from any lingering state.
517 // (src/queue.rs: clear 546 / restore_from_original 266;
518 // src/daemon.rs: stop 815, queue-end 353-354)
519 let mut q = Queue::new();
520 add_track(&mut q, "/music/a.mp3");
521 add_track(&mut q, "/music/b.mp3");
522 add_track(&mut q, "/music/c.mp3");
523 q.set_shuffle(ShuffleMode::All);
524
525 q.clear();
526 assert!(q.is_empty());
527 assert_eq!(q.len(), 0);
528
529 // Later the user toggles shuffle off: the queue must stay empty.
530 q.set_shuffle(ShuffleMode::None);
531 assert!(
532 q.is_empty(),
533 "cleared queue was resurrected from the stale shuffle snapshot (len = {})",
534 q.len()
535 );
536 assert_eq!(q.len(), 0);
537}
538
539#[test]
540fn test_shuffle_off_keeps_unplayed_duplicate_entries() {
541 // Duplicates are distinct queue entries: `restore_from_original` rebuilds
542 // by entry identity (played indices vs. the rest), never by path, so an
543 // unplayed duplicate of an already-played path must survive shuffle-off.
544 // (src/queue.rs: restore_from_original 266)
545 let mut q = Queue::new();
546 add_track(&mut q, "/music/a.mp3");
547 add_track(&mut q, "/music/b.mp3");
548 add_track(&mut q, "/music/a.mp3"); // duplicate entry (same path)
549
550 // Play the first two entries (position 1). The third entry is unplayed.
551 q.next();
552 assert_eq!(q.position(), 1);
553
554 // Position is 1 with len 3: the shuffled tail is a single element, so the
555 // shuffled indices stay identity and the restore is deterministic.
556 q.set_shuffle(ShuffleMode::All);
557 q.set_shuffle(ShuffleMode::None);
558
559 // All three entries must survive shuffle-off (duplicates are distinct
560 // queue entries, not a single path).
561 assert_eq!(
562 q.len(),
563 3,
564 "unplayed duplicate entry was dropped on shuffle-off (len = {})",
565 q.len()
566 );
567 assert_eq!(q.position(), 1);
568}
569
477// ---------- Track struct ---------- 570// ---------- Track struct ----------
478 571
479#[test] 572#[test]