From 1e48765ab39a679abcc4eac6927ad3bb58f7b438 Mon Sep 17 00:00:00 2001 From: salmonik Date: Thu, 4 Jun 2026 00:21:46 +0200 Subject: dirty, broken commit --- tests/database.rs | 393 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 392 insertions(+), 1 deletion(-) (limited to 'tests/database.rs') diff --git a/tests/database.rs b/tests/database.rs index 6cd870e..adbf535 100644 --- a/tests/database.rs +++ b/tests/database.rs @@ -5,7 +5,7 @@ * https://codeberg.org/salmonik/RSPlayer */ -use rsp::database::{extract_metadata, is_audio_file}; +use rsp::database::{Database, extract_metadata, is_audio_file}; use std::path::PathBuf; #[test] @@ -90,3 +90,394 @@ fn test_extract_metadata_no_parent() { assert_eq!(album, "Unknown"); assert_eq!(title, "song"); } + +fn seed_test_db(db: &Database) { + let conn: &rusqlite::Connection = db.conn(); + conn.execute_batch( + "INSERT INTO artists (id, name) VALUES (1, 'Metallica'), (2, 'Miles Davis'), (3, 'Aphex Twin'); + INSERT INTO albums (id, artist_id, title) VALUES + (1, 1, 'Master of Puppets'), + (2, 1, 'Ride the Lightning'), + (3, 2, 'Kind of Blue'), + (4, 3, 'Selected Ambient Works'); + INSERT INTO tracks (id, album_id, title, path, duration, track_number) VALUES + (1, 1, 'Battery', '/m/Metallica/Master of Puppets/01-Battery.mp3', 313, 1), + (2, 1, 'Master of Puppets', '/m/Metallica/Master of Puppets/02-Master of Puppets.mp3', 515, 2), + (3, 2, 'Fight Fire with Fire', '/m/Metallica/Ride the Lightning/01-Fight Fire with Fire.mp3', 285, 1), + (4, 3, 'So What', '/m/Miles Davis/Kind of Blue/01-So What.mp3', 562, 1), + (5, 4, 'Xtal', '/m/Aphex Twin/Selected Ambient Works/01-Xtal.mp3', 437, 1);", + ) + .unwrap(); +} + +#[test] +fn test_complete_artists_prefix() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + let results = db.complete_artists("M").unwrap(); + assert_eq!(results.len(), 2); + assert!(results.contains(&"Metallica".to_string())); + assert!(results.contains(&"Miles Davis".to_string())); +} + +#[test] +fn test_complete_artists_prefix_lowercase() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + let results = db.complete_artists("m").unwrap(); + assert!( + results.contains(&"Metallica".to_string()), + "LIKE should be case-insensitive" + ); +} + +#[test] +fn test_complete_artists_no_match() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + let results = db.complete_artists("Z").unwrap(); + assert!(results.is_empty()); +} + +#[test] +fn test_complete_artists_empty_prefix() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + let results = db.complete_artists("").unwrap(); + assert_eq!(results.len(), 3); +} + +#[test] +fn test_complete_albums_with_artist_prefix() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + let results = db.complete_albums("Metallica/").unwrap(); + assert_eq!(results.len(), 2); + assert!(results.contains(&"Master of Puppets".to_string())); + assert!(results.contains(&"Ride the Lightning".to_string())); +} + +#[test] +fn test_complete_albums_with_album_prefix() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + let results = db.complete_albums("Metallica/R").unwrap(); + assert_eq!(results.len(), 1); + assert_eq!(results[0], "Ride the Lightning"); +} + +#[test] +fn test_complete_albums_unknown_artist() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + let results = db.complete_albums("Unknown/").unwrap(); + assert!(results.is_empty()); +} + +#[test] +fn test_complete_albums_no_slash() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + let results = db.complete_albums("Metallica").unwrap(); + assert!(results.is_empty(), "needs trailing slash"); +} + +#[test] +fn test_complete_tracks_full_path() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + let results = db.complete_tracks("Metallica/Master of Puppets/").unwrap(); + assert_eq!(results.len(), 2); + assert!(results.contains(&"Battery".to_string())); + assert!(results.contains(&"Master of Puppets".to_string())); +} + +#[test] +fn test_complete_tracks_with_prefix() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + let results = db.complete_tracks("Metallica/Master of Puppets/B").unwrap(); + assert_eq!(results.len(), 1); + assert_eq!(results[0], "Battery"); +} + +#[test] +fn test_complete_tracks_unknown_album() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + let results = db.complete_tracks("Metallica/Nonexistent/").unwrap(); + assert!(results.is_empty()); +} + +#[test] +fn test_complete_tracks_too_few_parts() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + let results = db.complete_tracks("Metallica").unwrap(); + assert!(results.is_empty()); +} + +#[test] +fn test_complete_empty_db() { + let db = Database::open_in_memory().unwrap(); + assert!(db.complete_artists("").unwrap().is_empty()); + assert!(db.complete_albums("x/").unwrap().is_empty()); + assert!(db.complete_tracks("x/y/").unwrap().is_empty()); +} + +// --- find_tracks_by_album tests --- + +#[test] +fn test_find_tracks_by_album_all() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + let tracks = db + .find_tracks_by_album("Metallica", "Master of Puppets") + .unwrap(); + assert_eq!(tracks.len(), 2); + assert_eq!(tracks[0].title, "Battery"); + assert_eq!(tracks[1].title, "Master of Puppets"); + assert_eq!(tracks[0].artist_name.as_deref(), Some("Metallica")); + assert_eq!(tracks[0].album_title.as_deref(), Some("Master of Puppets")); +} + +#[test] +fn test_find_tracks_by_album_single_track() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + let tracks = db + .find_tracks_by_album("Miles Davis", "Kind of Blue") + .unwrap(); + assert_eq!(tracks.len(), 1); + assert_eq!(tracks[0].title, "So What"); +} + +#[test] +fn test_find_tracks_by_album_unknown_artist() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + let tracks = db + .find_tracks_by_album("Nonexistent", "Master of Puppets") + .unwrap(); + assert!(tracks.is_empty()); +} + +#[test] +fn test_find_tracks_by_album_unknown_album() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + let tracks = db.find_tracks_by_album("Metallica", "Nonexistent").unwrap(); + assert!(tracks.is_empty()); +} + +#[test] +fn test_find_tracks_by_album_case_sensitive_artist() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + // SQLite = is case-sensitive for TEXT (unless NOCASE collation) + let tracks = db + .find_tracks_by_album("metallica", "Master of Puppets") + .unwrap(); + assert!( + tracks.is_empty(), + "artist name match should be case-sensitive" + ); +} + +#[test] +fn test_find_tracks_by_album_ordered_by_track_number() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + let tracks = db + .find_tracks_by_album("Metallica", "Master of Puppets") + .unwrap(); + assert_eq!(tracks[0].track_number, Some(1)); + assert_eq!(tracks[1].track_number, Some(2)); +} + +// --- find_track_by_parts tests --- + +#[test] +fn test_find_track_by_parts_exact() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + let track = db + .find_track_by_parts("Metallica", "Master of Puppets", "Battery") + .unwrap(); + assert!(track.is_some()); + let t = track.unwrap(); + assert_eq!(t.title, "Battery"); + assert_eq!(t.artist_name.as_deref(), Some("Metallica")); + assert_eq!(t.album_title.as_deref(), Some("Master of Puppets")); +} + +#[test] +fn test_find_track_by_parts_prefix() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + let track = db + .find_track_by_parts("Metallica", "Master of Puppets", "B") + .unwrap(); + assert!(track.is_some()); + assert_eq!(track.unwrap().title, "Battery"); +} + +#[test] +fn test_find_track_by_parts_no_match_track() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + let track = db + .find_track_by_parts("Metallica", "Master of Puppets", "Z") + .unwrap(); + assert!(track.is_none()); +} + +#[test] +fn test_find_track_by_parts_no_match_album() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + let track = db + .find_track_by_parts("Metallica", "Nonexistent", "B") + .unwrap(); + assert!(track.is_none()); +} + +#[test] +fn test_find_track_by_parts_no_match_artist() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + let track = db + .find_track_by_parts("Nonexistent", "Master of Puppets", "B") + .unwrap(); + assert!(track.is_none()); +} + +#[test] +fn test_find_track_by_parts_case_sensitive() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + let track = db + .find_track_by_parts("metallica", "Master of Puppets", "Battery") + .unwrap(); + assert!(track.is_none(), "artist match should be case-sensitive"); +} + +// --- resolve_path tests --- + +#[test] +fn test_resolve_path_two_parts_album() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + let result = db.resolve_path("Metallica/Master of Puppets").unwrap(); + assert!(result.is_some()); + let tracks = result.unwrap(); + assert_eq!(tracks.len(), 2); + assert_eq!(tracks[0].title, "Battery"); +} + +#[test] +fn test_resolve_path_two_parts_trailing_slash() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + let result = db.resolve_path("Metallica/Master of Puppets/").unwrap(); + assert!(result.is_some()); + let tracks = result.unwrap(); + assert_eq!(tracks.len(), 2); +} + +#[test] +fn test_resolve_path_three_parts_track() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + let result = db + .resolve_path("Metallica/Master of Puppets/Battery") + .unwrap(); + assert!(result.is_some()); + let tracks = result.unwrap(); + assert_eq!(tracks.len(), 1); + assert_eq!(tracks[0].title, "Battery"); +} + +#[test] +fn test_resolve_path_three_parts_track_prefix() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + let result = db.resolve_path("Metallica/Master of Puppets/B").unwrap(); + assert!(result.is_some()); + let tracks = result.unwrap(); + assert_eq!(tracks.len(), 1); + assert_eq!(tracks[0].title, "Battery"); +} + +#[test] +fn test_resolve_path_single_part_returns_none() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + let result = db.resolve_path("Metallica").unwrap(); + assert!( + result.is_none(), + "single part should return None for fallback" + ); +} + +#[test] +fn test_resolve_path_no_match_album() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + let result = db.resolve_path("Metallica/Nonexistent").unwrap(); + assert!(result.is_some()); + assert!(result.unwrap().is_empty()); +} + +#[test] +fn test_resolve_path_no_match_track() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + let result = db.resolve_path("Metallica/Master of Puppets/Z").unwrap(); + assert!(result.is_some()); + assert!(result.unwrap().is_empty()); +} + +#[test] +fn test_resolve_path_empty_db() { + let db = Database::open_in_memory().unwrap(); + assert!(db.resolve_path("Artist/Album").unwrap().unwrap().is_empty()); + assert!( + db.resolve_path("Artist/Album/Track") + .unwrap() + .unwrap() + .is_empty() + ); + assert!(db.resolve_path("Artist").unwrap().is_none()); +} + +// --- Track conversion helper tests --- + +#[test] +fn test_find_tracks_by_album_returns_full_metadata() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + let tracks = db + .find_tracks_by_album("Metallica", "Ride the Lightning") + .unwrap(); + assert_eq!(tracks.len(), 1); + let t = &tracks[0]; + assert_eq!(t.artist_name.as_deref(), Some("Metallica")); + assert_eq!(t.album_title.as_deref(), Some("Ride the Lightning")); + assert_eq!(t.title, "Fight Fire with Fire"); + assert!(t.path.to_string_lossy().contains("Ride the Lightning")); +} + +#[test] +fn test_find_track_by_parts_returns_full_metadata() { + let db = Database::open_in_memory().unwrap(); + seed_test_db(&db); + let t = db + .find_track_by_parts("Aphex Twin", "Selected Ambient Works", "Xtal") + .unwrap() + .expect("track should be found"); + assert_eq!(t.artist_name.as_deref(), Some("Aphex Twin")); + assert_eq!(t.album_title.as_deref(), Some("Selected Ambient Works")); + assert_eq!(t.title, "Xtal"); + assert_eq!(t.track_number, Some(1)); +} -- cgit v1.2.3