From b34cc9c6629121648d1341172e89b10577b477ff Mon Sep 17 00:00:00 2001 From: Wojciech Kozlowski Date: Thu, 15 Feb 2024 20:44:02 +0100 Subject: [PATCH] Complete unit tests --- src/core/database/json/testmod.rs | 10 +- src/core/library/beets/testmod.rs | 44 +++---- src/core/library/testmod.rs | 52 ++++----- src/tests.rs | 18 +-- src/tui/app/app.rs | 187 ++++++++++++++++++++++++++++-- src/tui/app/selection.rs | 69 ++++++++--- 6 files changed, 291 insertions(+), 89 deletions(-) diff --git a/src/core/database/json/testmod.rs b/src/core/database/json/testmod.rs index 4c3031e..c492aed 100644 --- a/src/core/database/json/testmod.rs +++ b/src/core/database/json/testmod.rs @@ -2,7 +2,7 @@ pub static DATABASE_JSON: &str = "{\ \"V20240210\":\ [\ {\ - \"name\":\"Album_Artist A\",\ + \"name\":\"Album_Artist ‘A’\",\ \"sort\":null,\ \"musicbrainz\":\"https://musicbrainz.org/artist/00000000-0000-0000-0000-000000000000\",\ \"properties\":{\ @@ -11,7 +11,7 @@ pub static DATABASE_JSON: &str = "{\ }\ },\ {\ - \"name\":\"Album_Artist B\",\ + \"name\":\"Album_Artist ‘B’\",\ \"sort\":null,\ \"musicbrainz\":\"https://musicbrainz.org/artist/11111111-1111-1111-1111-111111111111\",\ \"properties\":{\ @@ -24,13 +24,13 @@ pub static DATABASE_JSON: &str = "{\ }\ },\ {\ - \"name\":\"Album_Artist C\",\ - \"sort\":null,\ + \"name\":\"The Album_Artist ‘C’\",\ + \"sort\":\"Album_Artist ‘C’, The\",\ \"musicbrainz\":\"https://musicbrainz.org/artist/11111111-1111-1111-1111-111111111111\",\ \"properties\":{}\ },\ {\ - \"name\":\"Album_Artist D\",\ + \"name\":\"Album_Artist ‘D’\",\ \"sort\":null,\ \"musicbrainz\":null,\ \"properties\":{}\ diff --git a/src/core/library/beets/testmod.rs b/src/core/library/beets/testmod.rs index a2a38a7..e4f30f9 100644 --- a/src/core/library/beets/testmod.rs +++ b/src/core/library/beets/testmod.rs @@ -2,27 +2,27 @@ use once_cell::sync::Lazy; pub static LIBRARY_BEETS: Lazy> = Lazy::new(|| -> Vec { vec![ - String::from("Album_Artist A -*^- -*^- 1998 -*^- album_title a.a -*^- 1 -*^- track a.a.1 -*^- artist a.a.1 -*^- FLAC -*^- 992"), - String::from("Album_Artist A -*^- -*^- 1998 -*^- album_title a.a -*^- 2 -*^- track a.a.2 -*^- artist a.a.2.1; artist a.a.2.2 -*^- MP3 -*^- 320"), - String::from("Album_Artist A -*^- -*^- 1998 -*^- album_title a.a -*^- 3 -*^- track a.a.3 -*^- artist a.a.3 -*^- FLAC -*^- 1061"), - String::from("Album_Artist A -*^- -*^- 1998 -*^- album_title a.a -*^- 4 -*^- track a.a.4 -*^- artist a.a.4 -*^- FLAC -*^- 1042"), - String::from("Album_Artist A -*^- -*^- 2015 -*^- album_title a.b -*^- 1 -*^- track a.b.1 -*^- artist a.b.1 -*^- FLAC -*^- 1004"), - String::from("Album_Artist A -*^- -*^- 2015 -*^- album_title a.b -*^- 2 -*^- track a.b.2 -*^- artist a.b.2 -*^- FLAC -*^- 1077"), - String::from("Album_Artist B -*^- -*^- 2003 -*^- album_title b.a -*^- 1 -*^- track b.a.1 -*^- artist b.a.1 -*^- MP3 -*^- 190"), - String::from("Album_Artist B -*^- -*^- 2003 -*^- album_title b.a -*^- 2 -*^- track b.a.2 -*^- artist b.a.2.1; artist b.a.2.2 -*^- MP3 -*^- 120"), - String::from("Album_Artist B -*^- -*^- 2008 -*^- album_title b.b -*^- 1 -*^- track b.b.1 -*^- artist b.b.1 -*^- FLAC -*^- 1077"), - String::from("Album_Artist B -*^- -*^- 2008 -*^- album_title b.b -*^- 2 -*^- track b.b.2 -*^- artist b.b.2.1; artist b.b.2.2 -*^- MP3 -*^- 320"), - String::from("Album_Artist B -*^- -*^- 2009 -*^- album_title b.c -*^- 1 -*^- track b.c.1 -*^- artist b.c.1 -*^- MP3 -*^- 190"), - String::from("Album_Artist B -*^- -*^- 2009 -*^- album_title b.c -*^- 2 -*^- track b.c.2 -*^- artist b.c.2.1; artist b.c.2.2 -*^- MP3 -*^- 120"), - String::from("Album_Artist B -*^- -*^- 2015 -*^- album_title b.d -*^- 1 -*^- track b.d.1 -*^- artist b.d.1 -*^- MP3 -*^- 190"), - String::from("Album_Artist B -*^- -*^- 2015 -*^- album_title b.d -*^- 2 -*^- track b.d.2 -*^- artist b.d.2.1; artist b.d.2.2 -*^- MP3 -*^- 120"), - String::from("Album_Artist C -*^- -*^- 1985 -*^- album_title c.a -*^- 1 -*^- track c.a.1 -*^- artist c.a.1 -*^- MP3 -*^- 320"), - String::from("Album_Artist C -*^- -*^- 1985 -*^- album_title c.a -*^- 2 -*^- track c.a.2 -*^- artist c.a.2.1; artist c.a.2.2 -*^- MP3 -*^- 120"), - String::from("Album_Artist C -*^- -*^- 2018 -*^- album_title c.b -*^- 1 -*^- track c.b.1 -*^- artist c.b.1 -*^- FLAC -*^- 1041"), - String::from("Album_Artist C -*^- -*^- 2018 -*^- album_title c.b -*^- 2 -*^- track c.b.2 -*^- artist c.b.2.1; artist c.b.2.2 -*^- FLAC -*^- 756"), - String::from("Album_Artist D -*^- -*^- 1995 -*^- album_title d.a -*^- 1 -*^- track d.a.1 -*^- artist d.a.1 -*^- MP3 -*^- 120"), - String::from("Album_Artist D -*^- -*^- 1995 -*^- album_title d.a -*^- 2 -*^- track d.a.2 -*^- artist d.a.2.1; artist d.a.2.2 -*^- MP3 -*^- 120"), - String::from("Album_Artist D -*^- -*^- 2028 -*^- album_title d.b -*^- 1 -*^- track d.b.1 -*^- artist d.b.1 -*^- FLAC -*^- 841"), - String::from("Album_Artist D -*^- -*^- 2028 -*^- album_title d.b -*^- 2 -*^- track d.b.2 -*^- artist d.b.2.1; artist d.b.2.2 -*^- FLAC -*^- 756") + String::from("Album_Artist ‘A’ -*^- -*^- 1998 -*^- album_title a.a -*^- 1 -*^- track a.a.1 -*^- artist a.a.1 -*^- FLAC -*^- 992"), + String::from("Album_Artist ‘A’ -*^- -*^- 1998 -*^- album_title a.a -*^- 2 -*^- track a.a.2 -*^- artist a.a.2.1; artist a.a.2.2 -*^- MP3 -*^- 320"), + String::from("Album_Artist ‘A’ -*^- -*^- 1998 -*^- album_title a.a -*^- 3 -*^- track a.a.3 -*^- artist a.a.3 -*^- FLAC -*^- 1061"), + String::from("Album_Artist ‘A’ -*^- -*^- 1998 -*^- album_title a.a -*^- 4 -*^- track a.a.4 -*^- artist a.a.4 -*^- FLAC -*^- 1042"), + String::from("Album_Artist ‘A’ -*^- -*^- 2015 -*^- album_title a.b -*^- 1 -*^- track a.b.1 -*^- artist a.b.1 -*^- FLAC -*^- 1004"), + String::from("Album_Artist ‘A’ -*^- -*^- 2015 -*^- album_title a.b -*^- 2 -*^- track a.b.2 -*^- artist a.b.2 -*^- FLAC -*^- 1077"), + String::from("Album_Artist ‘B’ -*^- -*^- 2003 -*^- album_title b.a -*^- 1 -*^- track b.a.1 -*^- artist b.a.1 -*^- MP3 -*^- 190"), + String::from("Album_Artist ‘B’ -*^- -*^- 2003 -*^- album_title b.a -*^- 2 -*^- track b.a.2 -*^- artist b.a.2.1; artist b.a.2.2 -*^- MP3 -*^- 120"), + String::from("Album_Artist ‘B’ -*^- -*^- 2008 -*^- album_title b.b -*^- 1 -*^- track b.b.1 -*^- artist b.b.1 -*^- FLAC -*^- 1077"), + String::from("Album_Artist ‘B’ -*^- -*^- 2008 -*^- album_title b.b -*^- 2 -*^- track b.b.2 -*^- artist b.b.2.1; artist b.b.2.2 -*^- MP3 -*^- 320"), + String::from("Album_Artist ‘B’ -*^- -*^- 2009 -*^- album_title b.c -*^- 1 -*^- track b.c.1 -*^- artist b.c.1 -*^- MP3 -*^- 190"), + String::from("Album_Artist ‘B’ -*^- -*^- 2009 -*^- album_title b.c -*^- 2 -*^- track b.c.2 -*^- artist b.c.2.1; artist b.c.2.2 -*^- MP3 -*^- 120"), + String::from("Album_Artist ‘B’ -*^- -*^- 2015 -*^- album_title b.d -*^- 1 -*^- track b.d.1 -*^- artist b.d.1 -*^- MP3 -*^- 190"), + String::from("Album_Artist ‘B’ -*^- -*^- 2015 -*^- album_title b.d -*^- 2 -*^- track b.d.2 -*^- artist b.d.2.1; artist b.d.2.2 -*^- MP3 -*^- 120"), + String::from("The Album_Artist ‘C’ -*^- Album_Artist ‘C’, The -*^- 1985 -*^- album_title c.a -*^- 1 -*^- track c.a.1 -*^- artist c.a.1 -*^- MP3 -*^- 320"), + String::from("The Album_Artist ‘C’ -*^- Album_Artist ‘C’, The -*^- 1985 -*^- album_title c.a -*^- 2 -*^- track c.a.2 -*^- artist c.a.2.1; artist c.a.2.2 -*^- MP3 -*^- 120"), + String::from("The Album_Artist ‘C’ -*^- Album_Artist ‘C’, The -*^- 2018 -*^- album_title c.b -*^- 1 -*^- track c.b.1 -*^- artist c.b.1 -*^- FLAC -*^- 1041"), + String::from("The Album_Artist ‘C’ -*^- Album_Artist ‘C’, The -*^- 2018 -*^- album_title c.b -*^- 2 -*^- track c.b.2 -*^- artist c.b.2.1; artist c.b.2.2 -*^- FLAC -*^- 756"), + String::from("Album_Artist ‘D’ -*^- -*^- 1995 -*^- album_title d.a -*^- 1 -*^- track d.a.1 -*^- artist d.a.1 -*^- MP3 -*^- 120"), + String::from("Album_Artist ‘D’ -*^- -*^- 1995 -*^- album_title d.a -*^- 2 -*^- track d.a.2 -*^- artist d.a.2.1; artist d.a.2.2 -*^- MP3 -*^- 120"), + String::from("Album_Artist ‘D’ -*^- -*^- 2028 -*^- album_title d.b -*^- 1 -*^- track d.b.1 -*^- artist d.b.1 -*^- FLAC -*^- 841"), + String::from("Album_Artist ‘D’ -*^- -*^- 2028 -*^- album_title d.b -*^- 2 -*^- track d.b.2 -*^- artist d.b.2.1; artist d.b.2.2 -*^- FLAC -*^- 756") ] }); diff --git a/src/core/library/testmod.rs b/src/core/library/testmod.rs index 1eb2787..af2ed68 100644 --- a/src/core/library/testmod.rs +++ b/src/core/library/testmod.rs @@ -5,7 +5,7 @@ use crate::core::{collection::track::Format, library::Item}; pub static LIBRARY_ITEMS: Lazy> = Lazy::new(|| -> Vec { vec![ Item { - album_artist: String::from("Album_Artist A"), + album_artist: String::from("Album_Artist ‘A’"), album_artist_sort: None, album_year: 1998, album_title: String::from("album_title a.a"), @@ -16,7 +16,7 @@ pub static LIBRARY_ITEMS: Lazy> = Lazy::new(|| -> Vec { track_bitrate: 992, }, Item { - album_artist: String::from("Album_Artist A"), + album_artist: String::from("Album_Artist ‘A’"), album_artist_sort: None, album_year: 1998, album_title: String::from("album_title a.a"), @@ -30,7 +30,7 @@ pub static LIBRARY_ITEMS: Lazy> = Lazy::new(|| -> Vec { track_bitrate: 320, }, Item { - album_artist: String::from("Album_Artist A"), + album_artist: String::from("Album_Artist ‘A’"), album_artist_sort: None, album_year: 1998, album_title: String::from("album_title a.a"), @@ -41,7 +41,7 @@ pub static LIBRARY_ITEMS: Lazy> = Lazy::new(|| -> Vec { track_bitrate: 1061, }, Item { - album_artist: String::from("Album_Artist A"), + album_artist: String::from("Album_Artist ‘A’"), album_artist_sort: None, album_year: 1998, album_title: String::from("album_title a.a"), @@ -52,7 +52,7 @@ pub static LIBRARY_ITEMS: Lazy> = Lazy::new(|| -> Vec { track_bitrate: 1042, }, Item { - album_artist: String::from("Album_Artist A"), + album_artist: String::from("Album_Artist ‘A’"), album_artist_sort: None, album_year: 2015, album_title: String::from("album_title a.b"), @@ -63,7 +63,7 @@ pub static LIBRARY_ITEMS: Lazy> = Lazy::new(|| -> Vec { track_bitrate: 1004, }, Item { - album_artist: String::from("Album_Artist A"), + album_artist: String::from("Album_Artist ‘A’"), album_artist_sort: None, album_year: 2015, album_title: String::from("album_title a.b"), @@ -74,7 +74,7 @@ pub static LIBRARY_ITEMS: Lazy> = Lazy::new(|| -> Vec { track_bitrate: 1077, }, Item { - album_artist: String::from("Album_Artist B"), + album_artist: String::from("Album_Artist ‘B’"), album_artist_sort: None, album_year: 2003, album_title: String::from("album_title b.a"), @@ -85,7 +85,7 @@ pub static LIBRARY_ITEMS: Lazy> = Lazy::new(|| -> Vec { track_bitrate: 190, }, Item { - album_artist: String::from("Album_Artist B"), + album_artist: String::from("Album_Artist ‘B’"), album_artist_sort: None, album_year: 2003, album_title: String::from("album_title b.a"), @@ -99,7 +99,7 @@ pub static LIBRARY_ITEMS: Lazy> = Lazy::new(|| -> Vec { track_bitrate: 120, }, Item { - album_artist: String::from("Album_Artist B"), + album_artist: String::from("Album_Artist ‘B’"), album_artist_sort: None, album_year: 2008, album_title: String::from("album_title b.b"), @@ -110,7 +110,7 @@ pub static LIBRARY_ITEMS: Lazy> = Lazy::new(|| -> Vec { track_bitrate: 1077, }, Item { - album_artist: String::from("Album_Artist B"), + album_artist: String::from("Album_Artist ‘B’"), album_artist_sort: None, album_year: 2008, album_title: String::from("album_title b.b"), @@ -124,7 +124,7 @@ pub static LIBRARY_ITEMS: Lazy> = Lazy::new(|| -> Vec { track_bitrate: 320, }, Item { - album_artist: String::from("Album_Artist B"), + album_artist: String::from("Album_Artist ‘B’"), album_artist_sort: None, album_year: 2009, album_title: String::from("album_title b.c"), @@ -135,7 +135,7 @@ pub static LIBRARY_ITEMS: Lazy> = Lazy::new(|| -> Vec { track_bitrate: 190, }, Item { - album_artist: String::from("Album_Artist B"), + album_artist: String::from("Album_Artist ‘B’"), album_artist_sort: None, album_year: 2009, album_title: String::from("album_title b.c"), @@ -149,7 +149,7 @@ pub static LIBRARY_ITEMS: Lazy> = Lazy::new(|| -> Vec { track_bitrate: 120, }, Item { - album_artist: String::from("Album_Artist B"), + album_artist: String::from("Album_Artist ‘B’"), album_artist_sort: None, album_year: 2015, album_title: String::from("album_title b.d"), @@ -160,7 +160,7 @@ pub static LIBRARY_ITEMS: Lazy> = Lazy::new(|| -> Vec { track_bitrate: 190, }, Item { - album_artist: String::from("Album_Artist B"), + album_artist: String::from("Album_Artist ‘B’"), album_artist_sort: None, album_year: 2015, album_title: String::from("album_title b.d"), @@ -174,8 +174,8 @@ pub static LIBRARY_ITEMS: Lazy> = Lazy::new(|| -> Vec { track_bitrate: 120, }, Item { - album_artist: String::from("Album_Artist C"), - album_artist_sort: None, + album_artist: String::from("The Album_Artist ‘C’"), + album_artist_sort: Some(String::from("Album_Artist ‘C’, The")), album_year: 1985, album_title: String::from("album_title c.a"), track_number: 1, @@ -185,8 +185,8 @@ pub static LIBRARY_ITEMS: Lazy> = Lazy::new(|| -> Vec { track_bitrate: 320, }, Item { - album_artist: String::from("Album_Artist C"), - album_artist_sort: None, + album_artist: String::from("The Album_Artist ‘C’"), + album_artist_sort: Some(String::from("Album_Artist ‘C’, The")), album_year: 1985, album_title: String::from("album_title c.a"), track_number: 2, @@ -199,8 +199,8 @@ pub static LIBRARY_ITEMS: Lazy> = Lazy::new(|| -> Vec { track_bitrate: 120, }, Item { - album_artist: String::from("Album_Artist C"), - album_artist_sort: None, + album_artist: String::from("The Album_Artist ‘C’"), + album_artist_sort: Some(String::from("Album_Artist ‘C’, The")), album_year: 2018, album_title: String::from("album_title c.b"), track_number: 1, @@ -210,8 +210,8 @@ pub static LIBRARY_ITEMS: Lazy> = Lazy::new(|| -> Vec { track_bitrate: 1041, }, Item { - album_artist: String::from("Album_Artist C"), - album_artist_sort: None, + album_artist: String::from("The Album_Artist ‘C’"), + album_artist_sort: Some(String::from("Album_Artist ‘C’, The")), album_year: 2018, album_title: String::from("album_title c.b"), track_number: 2, @@ -224,7 +224,7 @@ pub static LIBRARY_ITEMS: Lazy> = Lazy::new(|| -> Vec { track_bitrate: 756, }, Item { - album_artist: String::from("Album_Artist D"), + album_artist: String::from("Album_Artist ‘D’"), album_artist_sort: None, album_year: 1995, album_title: String::from("album_title d.a"), @@ -235,7 +235,7 @@ pub static LIBRARY_ITEMS: Lazy> = Lazy::new(|| -> Vec { track_bitrate: 120, }, Item { - album_artist: String::from("Album_Artist D"), + album_artist: String::from("Album_Artist ‘D’"), album_artist_sort: None, album_year: 1995, album_title: String::from("album_title d.a"), @@ -249,7 +249,7 @@ pub static LIBRARY_ITEMS: Lazy> = Lazy::new(|| -> Vec { track_bitrate: 120, }, Item { - album_artist: String::from("Album_Artist D"), + album_artist: String::from("Album_Artist ‘D’"), album_artist_sort: None, album_year: 2028, album_title: String::from("album_title d.b"), @@ -260,7 +260,7 @@ pub static LIBRARY_ITEMS: Lazy> = Lazy::new(|| -> Vec { track_bitrate: 841, }, Item { - album_artist: String::from("Album_Artist D"), + album_artist: String::from("Album_Artist ‘D’"), album_artist_sort: None, album_year: 2028, album_title: String::from("album_title d.b"), diff --git a/src/tests.rs b/src/tests.rs index db2b4f8..9b9ab6e 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -3,7 +3,7 @@ macro_rules! library_collection { vec![ Artist { id: ArtistId { - name: "Album_Artist A".to_string(), + name: "Album_Artist ‘A’".to_string(), }, sort: None, musicbrainz: None, @@ -98,7 +98,7 @@ macro_rules! library_collection { }, Artist { id: ArtistId { - name: "Album_Artist B".to_string(), + name: "Album_Artist ‘B’".to_string(), }, sort: None, musicbrainz: None, @@ -240,9 +240,11 @@ macro_rules! library_collection { }, Artist { id: ArtistId { - name: "Album_Artist C".to_string(), + name: "The Album_Artist ‘C’".to_string(), }, - sort: None, + sort: Some(ArtistId { + name: "Album_Artist ‘C’, The".to_string(), + }), musicbrainz: None, properties: HashMap::new(), albums: vec![ @@ -316,7 +318,7 @@ macro_rules! library_collection { }, Artist { id: ArtistId { - name: "Album_Artist D".to_string(), + name: "Album_Artist ‘D’".to_string(), }, sort: None, musicbrainz: None, @@ -400,7 +402,7 @@ macro_rules! full_collection { let mut iter = collection.iter_mut(); let artist_a = iter.next().unwrap(); - assert_eq!(artist_a.id.name, "Album_Artist A"); + assert_eq!(artist_a.id.name, "Album_Artist ‘A’"); artist_a.musicbrainz = Some( MusicBrainz::new( @@ -421,7 +423,7 @@ macro_rules! full_collection { ]); let artist_b = iter.next().unwrap(); - assert_eq!(artist_b.id.name, "Album_Artist B"); + assert_eq!(artist_b.id.name, "Album_Artist ‘B’"); artist_b.musicbrainz = Some( MusicBrainz::new( @@ -443,7 +445,7 @@ macro_rules! full_collection { ]); let artist_c = iter.next().unwrap(); - assert_eq!(artist_c.id.name, "Album_Artist C"); + assert_eq!(artist_c.id.name, "The Album_Artist ‘C’"); artist_c.musicbrainz = Some( MusicBrainz::new( diff --git a/src/tui/app/app.rs b/src/tui/app/app.rs index a3f324b..ef7d842 100644 --- a/src/tui/app/app.rs +++ b/src/tui/app/app.rs @@ -3,7 +3,7 @@ use musichoard::collection::Collection; use crate::tui::{ - app::selection::{Delta, IdSelection, Selection, ListSelection}, + app::selection::{Delta, IdSelection, ListSelection, Selection}, lib::IMusicHoard, }; @@ -144,7 +144,12 @@ pub struct App { // FIXME: is it possible to use a wrapper struct? - when state() is called return a wrapper // around App which will contain App. orig: Option, - memo: Vec<(Option, bool)>, + memo: Vec, +} + +struct AppSearchMemo { + index: Option, + char: bool, } impl App { @@ -306,31 +311,31 @@ impl IAppInteractSearch for App { let collection = self.music_hoard.get_collection(); let search = self.state.as_mut().unwrap_search(); search.push(ch); - let prev = self + let index = self .selection .incremental_artist_search(collection, search, false); - self.memo.push((prev, true)); + self.memo.push(AppSearchMemo { index, char: true }); } fn search_next(&mut self) { let collection = self.music_hoard.get_collection(); let search = self.state.as_mut().unwrap_search(); if !search.is_empty() { - let prev = self + let index = self .selection .incremental_artist_search(collection, search, true); - self.memo.push((prev, false)); + self.memo.push(AppSearchMemo { index, char: false }); } } fn step_back(&mut self) { let collection = self.music_hoard.get_collection(); - if let Some((prev, pop_char)) = self.memo.pop() { - if pop_char { + if let Some(memo) = self.memo.pop() { + if memo.char { let search = self.state.as_mut().unwrap_search(); search.pop(); } - self.selection.select_artist(collection, prev); + self.selection.select_artist(collection, memo.index); } } @@ -880,17 +885,23 @@ mod tests { assert_eq!(app.selection.active, Category::Album); assert_eq!(app.selection.artist.state.list.selected(), Some(0)); + app.append_character('\''); app.append_character('c'); + app.append_character('\''); assert_eq!(app.selection.active, Category::Album); assert_eq!(app.selection.artist.state.list.selected(), Some(2)); - app.remove_character(); + app.step_back(); + app.step_back(); + app.step_back(); assert_eq!(app.selection.active, Category::Album); assert_eq!(app.selection.artist.state.list.selected(), Some(0)); + app.append_character('\''); app.append_character('b'); + app.append_character('\''); assert_eq!(app.selection.active, Category::Album); assert_eq!(app.selection.artist.state.list.selected(), Some(1)); @@ -901,4 +912,160 @@ mod tests { assert_eq!(app.selection.active, Category::Album); assert_eq!(app.selection.artist.state.list.selected(), Some(1)); } + + #[test] + fn search_next() { + let mut app = App::new(music_hoard(COLLECTION.to_owned())); + assert!(app.state().is_browse()); + + app.increment_selection(Delta::Line); + app.increment_category(); + + assert_eq!(app.selection.active, Category::Album); + assert_eq!(app.selection.artist.state.list.selected(), Some(1)); + + app.begin_search(); + assert!(app.state().is_search()); + + assert_eq!(app.selection.active, Category::Album); + assert_eq!(app.selection.artist.state.list.selected(), Some(0)); + + app.step_back(); + + assert_eq!(app.selection.active, Category::Album); + assert_eq!(app.selection.artist.state.list.selected(), Some(0)); + + app.append_character('a'); + + app.search_next(); + + assert_eq!(app.selection.active, Category::Album); + assert_eq!(app.selection.artist.state.list.selected(), Some(1)); + + app.search_next(); + + assert_eq!(app.selection.active, Category::Album); + assert_eq!(app.selection.artist.state.list.selected(), Some(2)); + + app.search_next(); + + assert_eq!(app.selection.active, Category::Album); + assert_eq!(app.selection.artist.state.list.selected(), Some(3)); + + app.search_next(); + + assert_eq!(app.selection.active, Category::Album); + assert_eq!(app.selection.artist.state.list.selected(), Some(3)); + + app.step_back(); + + assert_eq!(app.selection.active, Category::Album); + assert_eq!(app.selection.artist.state.list.selected(), Some(3)); + + app.step_back(); + + assert_eq!(app.selection.active, Category::Album); + assert_eq!(app.selection.artist.state.list.selected(), Some(2)); + + app.step_back(); + + assert_eq!(app.selection.active, Category::Album); + assert_eq!(app.selection.artist.state.list.selected(), Some(1)); + + app.step_back(); + + assert_eq!(app.selection.active, Category::Album); + assert_eq!(app.selection.artist.state.list.selected(), Some(0)); + + app.step_back(); + + assert_eq!(app.selection.active, Category::Album); + assert_eq!(app.selection.artist.state.list.selected(), Some(0)); + } + + #[test] + fn cancel_search() { + let mut app = App::new(music_hoard(COLLECTION.to_owned())); + assert!(app.state().is_browse()); + + app.increment_selection(Delta::Line); + app.increment_category(); + + assert_eq!(app.selection.active, Category::Album); + assert_eq!(app.selection.artist.state.list.selected(), Some(1)); + + app.begin_search(); + assert!(app.state().is_search()); + + assert_eq!(app.selection.active, Category::Album); + assert_eq!(app.selection.artist.state.list.selected(), Some(0)); + + app.append_character('a'); + app.append_character('l'); + app.append_character('b'); + app.append_character('u'); + app.append_character('m'); + app.append_character('_'); + app.append_character('a'); + app.append_character('r'); + app.append_character('t'); + app.append_character('i'); + app.append_character('s'); + app.append_character('t'); + app.append_character(' '); + app.append_character('\''); + app.append_character('c'); + app.append_character('\''); + + assert_eq!(app.selection.active, Category::Album); + assert_eq!(app.selection.artist.state.list.selected(), Some(2)); + + app.cancel_search(); + + assert_eq!(app.selection.active, Category::Album); + assert_eq!(app.selection.artist.state.list.selected(), Some(1)); + } + + #[test] + fn empty_search() { + let mut app = App::new(music_hoard(vec![])); + assert!(app.state().is_browse()); + + app.increment_selection(Delta::Line); + app.increment_category(); + + assert_eq!(app.selection.active, Category::Album); + assert_eq!(app.selection.artist.state.list.selected(), None); + + app.begin_search(); + assert!(app.state().is_search()); + + assert_eq!(app.selection.active, Category::Album); + assert_eq!(app.selection.artist.state.list.selected(), None); + + app.append_character('a'); + + assert_eq!(app.selection.active, Category::Album); + assert_eq!(app.selection.artist.state.list.selected(), None); + + app.search_next(); + + assert_eq!(app.selection.active, Category::Album); + assert_eq!(app.selection.artist.state.list.selected(), None); + + app.step_back(); + + assert_eq!(app.selection.active, Category::Album); + assert_eq!(app.selection.artist.state.list.selected(), None); + + app.step_back(); + + assert_eq!(app.selection.active, Category::Album); + assert_eq!(app.selection.artist.state.list.selected(), None); + + app.cancel_search(); + + assert_eq!(app.selection.active, Category::Album); + assert_eq!(app.selection.artist.state.list.selected(), None); + } } diff --git a/src/tui/app/selection.rs b/src/tui/app/selection.rs index c81df44..cf14785 100644 --- a/src/tui/app/selection.rs +++ b/src/tui/app/selection.rs @@ -214,7 +214,8 @@ impl ArtistSelection { } } - // FIXME: use aho_corasick for normalization + // FIXME: use aho_corasick for normalization - AhoCorasick does not implement PartialEq. It + // makes more sense to be places in app.rs as it would make ArtistSelection non-trivial. fn normalize_search(search: &str, lowercase: bool, asciify: bool) -> String { let normalized = if lowercase { search.to_lowercase() @@ -910,46 +911,78 @@ mod tests { fn artist_incremental_search() { let artists = &COLLECTION; + // Empty collection. let mut sel = ArtistSelection::initialise(&[]); assert_eq!(sel.state.list.selected(), None); - sel.incremental_search(artists, "album_artist a"); + sel.incremental_search(artists, "album_artist 'a'", false); assert_eq!(sel.state.list.selected(), None); + // Basic test, first element. let mut sel = ArtistSelection::initialise(artists); assert_eq!(sel.state.list.selected(), Some(0)); - sel.incremental_search(artists, "album_artist a"); + sel.incremental_search(artists, "", false); assert_eq!(sel.state.list.selected(), Some(0)); + sel.incremental_search(artists, "album_artist ", false); + assert_eq!(sel.state.list.selected(), Some(0)); + + sel.incremental_search(artists, "album_artist 'a'", false); + assert_eq!(sel.state.list.selected(), Some(0)); + + // Basic test, non-first element. sel.reinitialise(artists, None); + + sel.incremental_search(artists, "album_artist ", false); assert_eq!(sel.state.list.selected(), Some(0)); - sel.incremental_search(artists, "album_artist b"); - assert_eq!(sel.state.list.selected(), Some(1)); - - sel.reinitialise(artists, None); - assert_eq!(sel.state.list.selected(), Some(0)); - - sel.incremental_search(artists, "Album_Artist B"); - assert_eq!(sel.state.list.selected(), Some(1)); - - sel.reinitialise(artists, None); - assert_eq!(sel.state.list.selected(), Some(0)); - - sel.incremental_search(artists, "album_artist ba"); + sel.incremental_search(artists, "album_artist 'c'", false); assert_eq!(sel.state.list.selected(), Some(2)); + // Non-lowercase. sel.reinitialise(artists, None); + + sel.incremental_search(artists, "Album_Artist ", false); assert_eq!(sel.state.list.selected(), Some(0)); - sel.incremental_search(artists, "album_artist c"); + sel.incremental_search(artists, "Album_Artist 'C'", false); assert_eq!(sel.state.list.selected(), Some(2)); + // Non-ascii. sel.reinitialise(artists, None); + + sel.incremental_search(artists, "album_artist ", false); assert_eq!(sel.state.list.selected(), Some(0)); - sel.incremental_search(artists, "album_artist d"); + sel.incremental_search(artists, "album_artist ‘c’", false); + assert_eq!(sel.state.list.selected(), Some(2)); + + // Stop at name, not sort name. + sel.reinitialise(artists, None); + + sel.incremental_search(artists, "the", false); + assert_eq!(sel.state.list.selected(), Some(2)); + + sel.incremental_search(artists, "the album_artist 'c'", false); + assert_eq!(sel.state.list.selected(), Some(2)); + + // Search next with common prefix. + sel.reinitialise(artists, None); + + sel.incremental_search(artists, "album_artist ", false); + assert_eq!(sel.state.list.selected(), Some(0)); + + sel.incremental_search(artists, "album_artist ", true); + assert_eq!(sel.state.list.selected(), Some(1)); + + sel.incremental_search(artists, "album_artist ", true); + assert_eq!(sel.state.list.selected(), Some(2)); + + sel.incremental_search(artists, "album_artist ", true); + assert_eq!(sel.state.list.selected(), Some(3)); + + sel.incremental_search(artists, "album_artist ", true); assert_eq!(sel.state.list.selected(), Some(3)); } }