From 50dd1e373047cbdc381ba2cd2bbdf62225b0097c Mon Sep 17 00:00:00 2001 From: Wojciech Kozlowski Date: Sun, 12 Jan 2025 09:25:59 +0100 Subject: [PATCH] Load unit test --- src/external/database/serde/common.rs | 6 +- src/external/database/serde/deserialize.rs | 6 +- src/external/database/sql/mod.rs | 65 ++----- src/external/database/sql/testmod.rs | 202 +++++++++++++++++++++ 4 files changed, 222 insertions(+), 57 deletions(-) create mode 100644 src/external/database/sql/testmod.rs diff --git a/src/external/database/serde/common.rs b/src/external/database/serde/common.rs index 8a2207d..000fc8d 100644 --- a/src/external/database/serde/common.rs +++ b/src/external/database/serde/common.rs @@ -14,7 +14,7 @@ pub enum AlbumLibIdDef { } #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] -pub struct SerdeAlbumLibId(#[serde(with = "AlbumLibIdDef")] AlbumLibId); +pub struct SerdeAlbumLibId(#[serde(with = "AlbumLibIdDef")] pub AlbumLibId); impl From for AlbumLibId { fn from(value: SerdeAlbumLibId) -> Self { @@ -70,7 +70,7 @@ pub enum AlbumPrimaryTypeDef { } #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] -pub struct SerdeAlbumPrimaryType(#[serde(with = "AlbumPrimaryTypeDef")] AlbumPrimaryType); +pub struct SerdeAlbumPrimaryType(#[serde(with = "AlbumPrimaryTypeDef")] pub AlbumPrimaryType); impl From for AlbumPrimaryType { fn from(value: SerdeAlbumPrimaryType) -> Self { @@ -102,7 +102,7 @@ pub enum AlbumSecondaryTypeDef { } #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] -pub struct SerdeAlbumSecondaryType(#[serde(with = "AlbumSecondaryTypeDef")] AlbumSecondaryType); +pub struct SerdeAlbumSecondaryType(#[serde(with = "AlbumSecondaryTypeDef")] pub AlbumSecondaryType); impl From for AlbumSecondaryType { fn from(value: SerdeAlbumSecondaryType) -> Self { diff --git a/src/external/database/serde/deserialize.rs b/src/external/database/serde/deserialize.rs index bd1db1a..688dfc7 100644 --- a/src/external/database/serde/deserialize.rs +++ b/src/external/database/serde/deserialize.rs @@ -51,10 +51,12 @@ pub struct DeserializeAlbum { } #[derive(Clone, Debug, Deserialize)] -pub struct DeserializeMbRefOption(#[serde(with = "MbRefOptionDef")] MbRefOption); +pub struct DeserializeMbRefOption( + #[serde(with = "MbRefOptionDef")] pub MbRefOption, +); #[derive(Clone, Debug)] -pub struct DeserializeMbid(Mbid); +pub struct DeserializeMbid(pub Mbid); macro_rules! impl_from_for_mb_ref_option { ($ref:ty) => { diff --git a/src/external/database/sql/mod.rs b/src/external/database/sql/mod.rs index 559c9be..0cdfeae 100644 --- a/src/external/database/sql/mod.rs +++ b/src/external/database/sql/mod.rs @@ -198,19 +198,21 @@ impl ISqlDatabaseBackend<'conn>> IDatabase for SqlDatabase } } -// #[cfg(test)] -// pub mod testmod; +#[cfg(test)] +pub mod testmod; #[cfg(test)] mod tests { - use std::fs; - use std::collections::VecDeque; use mockall::{predicate, Sequence}; - use rusqlite::Connection; - use crate::core::{collection::Collection, testmod::FULL_COLLECTION}; + use crate::{ + core::{collection::Collection, testmod::FULL_COLLECTION}, + external::database::sql::testmod::{ + DATABASE_SQL_ALBUMS, DATABASE_SQL_ARTISTS, DATABASE_SQL_VERSION, + }, + }; use super::*; @@ -323,39 +325,21 @@ mod tests { #[test] fn load() { - let path = fs::canonicalize("./src/external/database/sql/testmod.db").unwrap(); - let db = Connection::open(path).unwrap(); - let mut tx = MockISqlTransactionBackend::new(); let mut seq = Sequence::new(); - let version_query = "SELECT value FROM database_metadata WHERE name = 'version'"; - let version: String = db.query_row(&version_query, (), |row| row.get(0)).unwrap(); - then!(tx, seq, expect_select_database_version).return_once(|| Ok(Some(version))); + then!(tx, seq, expect_select_database_version) + .return_once(|| Ok(Some(DATABASE_SQL_VERSION.to_string()))); - let artist_query = "SELECT name, sort, mbid, properties FROM artists"; - let mut artist_query = db.prepare(&artist_query).unwrap(); - let mut artist_rows = artist_query.query(()).unwrap(); - let mut de_artists = vec![]; - while let Some(row) = artist_rows.next().unwrap() { - de_artists.push(row.try_into().unwrap()); - } + let de_artists = DATABASE_SQL_ARTISTS.to_owned(); let artists: Collection = de_artists.iter().cloned().map(Into::into).collect(); then!(tx, seq, expect_select_all_artists).return_once(|| Ok(de_artists)); for artist in artists.iter() { - let album_query = - "SELECT title, lib_id, year, month, day, seq, mbid, primary_type, secondary_types - FROM albums WHERE artist_name = ?1"; - let mut album_query = db.prepare(&album_query).unwrap(); - let mut album_rows = album_query.query([artist.meta.id.name.clone()]).unwrap(); - let mut de_albums = vec![]; - while let Some(row) = album_rows.next().unwrap() { - de_albums.push(row.try_into().unwrap()); - } + let de_albums = DATABASE_SQL_ALBUMS.get(&artist.meta.id.name).unwrap(); then!(tx, seq, expect_select_artist_albums) .with(predicate::eq(artist.meta.id.name.clone())) - .return_once(|_| Ok(de_albums)); + .return_once(|_| Ok(de_albums.to_owned())); } then0!(tx, seq, expect_commit); @@ -366,29 +350,6 @@ mod tests { assert_eq!(read_data, expected); } - // #[test] - // fn reverse() { - // let input = DATABASE_JSON.to_owned(); - // let result = Ok(input.clone()); - - // let mut backend = MockISqlDatabaseBackend::new(); - // backend - // .expect_write() - // .with(predicate::eq(input)) - // .times(1) - // .return_once(|_| Ok(())); - // backend.expect_read().times(1).return_once(|| result); - // let mut database = SqlDatabase::new(backend); - - // let write_data = FULL_COLLECTION.to_owned(); - // database.save(&write_data).unwrap(); - // let read_data: Vec = database.load().unwrap(); - - // // Album information is not saved to disk. - // let expected = expected(); - // assert_eq!(read_data, expected); - // } - // #[test] // fn load_errors() { // let json = String::from(""); diff --git a/src/external/database/sql/testmod.rs b/src/external/database/sql/testmod.rs new file mode 100644 index 0000000..c03a880 --- /dev/null +++ b/src/external/database/sql/testmod.rs @@ -0,0 +1,202 @@ +use std::collections::HashMap; + +use once_cell::sync::Lazy; + +use crate::{ + collection::{ + album::{AlbumDate, AlbumLibId, AlbumPrimaryType}, + musicbrainz::MbRefOption, + }, + external::database::serde::{ + common::{SerdeAlbumDate, SerdeAlbumLibId, SerdeAlbumPrimaryType}, + deserialize::{ + DeserializeAlbum, DeserializeArtist, DeserializeMbRefOption, DeserializeMbid, + }, + }, +}; + +pub static DATABASE_SQL_VERSION: &str = "V20250103"; + +pub static DATABASE_SQL_ARTISTS: Lazy> = Lazy::new(|| { + vec![ + DeserializeArtist { + name: String::from("Album_Artist ‘A’"), + sort: None, + musicbrainz: DeserializeMbRefOption(MbRefOption::Some(DeserializeMbid( + "00000000-0000-0000-0000-000000000000".try_into().unwrap(), + ))), + properties: HashMap::from([ + ( + String::from("MusicButler"), + vec![String::from( + "https://www.musicbutler.io/artist-page/000000000", + )], + ), + ( + String::from("Qobuz"), + vec![String::from( + "https://www.qobuz.com/nl-nl/interpreter/artist-a/download-streaming-albums", + )], + ), + ]), + albums: vec![], + }, + DeserializeArtist { + name: String::from("Album_Artist ‘B’"), + sort: None, + musicbrainz: DeserializeMbRefOption(MbRefOption::Some(DeserializeMbid( + "11111111-1111-1111-1111-111111111111".try_into().unwrap(), + ))), + properties: HashMap::from([ + (String::from("MusicButler"), vec![ + String::from("https://www.musicbutler.io/artist-page/111111111"), + String::from("https://www.musicbutler.io/artist-page/111111112"), + ]), + (String::from("Bandcamp"), vec![ + String::from("https://artist-b.bandcamp.com/") + ]), + (String::from("Qobuz"), vec![ + String::from( + "https://www.qobuz.com/nl-nl/interpreter/artist-b/download-streaming-albums", + ) + ]), + ]), + albums: vec![], + }, + DeserializeArtist { + name: String::from("The Album_Artist ‘C’"), + sort: Some(String::from("Album_Artist ‘C’, The")), + musicbrainz: DeserializeMbRefOption(MbRefOption::CannotHaveMbid), + properties: HashMap::new(), + albums: vec![], + }, + DeserializeArtist { + name: String::from("Album_Artist ‘D’"), + sort: None, + musicbrainz: DeserializeMbRefOption(MbRefOption::None), + properties: HashMap::new(), + albums: vec![], + }, + ] +}); + +pub static DATABASE_SQL_ALBUMS: Lazy>> = Lazy::new(|| { + HashMap::from([ + ( + String::from("Album_Artist ‘A’"), + vec![ + DeserializeAlbum { + title: String::from("album_title a.a"), + lib_id: SerdeAlbumLibId(AlbumLibId::Value(1)), + date: SerdeAlbumDate(AlbumDate::new(Some(1998), None, None)), + seq: 1, + musicbrainz: DeserializeMbRefOption(MbRefOption::Some(DeserializeMbid( + "00000000-0000-0000-0000-000000000000".try_into().unwrap(), + ))), + primary_type: Some(SerdeAlbumPrimaryType(AlbumPrimaryType::Album)), + secondary_types: vec![], + }, + DeserializeAlbum { + title: String::from("album_title a.b"), + lib_id: SerdeAlbumLibId(AlbumLibId::Value(2)), + date: SerdeAlbumDate(AlbumDate::new(Some(2015), Some(4), None)), + seq: 1, + musicbrainz: DeserializeMbRefOption(MbRefOption::None), + primary_type: Some(SerdeAlbumPrimaryType(AlbumPrimaryType::Album)), + secondary_types: vec![], + }, + ], + ), + ( + String::from("Album_Artist ‘B’"), + vec![ + DeserializeAlbum { + title: String::from("album_title b.a"), + lib_id: SerdeAlbumLibId(AlbumLibId::Value(3)), + date: SerdeAlbumDate(AlbumDate::new(Some(2003), Some(6), Some(6))), + seq: 1, + musicbrainz: DeserializeMbRefOption(MbRefOption::None), + primary_type: Some(SerdeAlbumPrimaryType(AlbumPrimaryType::Album)), + secondary_types: vec![], + }, + DeserializeAlbum { + title: String::from("album_title b.b"), + lib_id: SerdeAlbumLibId(AlbumLibId::Value(4)), + date: SerdeAlbumDate(AlbumDate::new(Some(2008), None, None)), + seq: 3, + musicbrainz: DeserializeMbRefOption(MbRefOption::Some(DeserializeMbid( + "11111111-1111-1111-1111-111111111111".try_into().unwrap(), + ))), + primary_type: Some(SerdeAlbumPrimaryType(AlbumPrimaryType::Album)), + secondary_types: vec![], + }, + DeserializeAlbum { + title: String::from("album_title b.c"), + lib_id: SerdeAlbumLibId(AlbumLibId::Value(5)), + date: SerdeAlbumDate(AlbumDate::new(Some(2009), None, None)), + seq: 2, + musicbrainz: DeserializeMbRefOption(MbRefOption::Some(DeserializeMbid( + "11111111-1111-1111-1111-111111111112".try_into().unwrap(), + ))), + primary_type: Some(SerdeAlbumPrimaryType(AlbumPrimaryType::Album)), + secondary_types: vec![], + }, + DeserializeAlbum { + title: String::from("album_title b.d"), + lib_id: SerdeAlbumLibId(AlbumLibId::Value(6)), + date: SerdeAlbumDate(AlbumDate::new(Some(2015), None, None)), + seq: 4, + musicbrainz: DeserializeMbRefOption(MbRefOption::None), + primary_type: Some(SerdeAlbumPrimaryType(AlbumPrimaryType::Album)), + secondary_types: vec![], + }, + ], + ), + ( + String::from("The Album_Artist ‘C’"), + vec![ + DeserializeAlbum { + title: String::from("album_title c.a"), + lib_id: SerdeAlbumLibId(AlbumLibId::Value(7)), + date: SerdeAlbumDate(AlbumDate::new(Some(1985), None, None)), + seq: 0, + musicbrainz: DeserializeMbRefOption(MbRefOption::None), + primary_type: Some(SerdeAlbumPrimaryType(AlbumPrimaryType::Album)), + secondary_types: vec![], + }, + DeserializeAlbum { + title: String::from("album_title c.b"), + lib_id: SerdeAlbumLibId(AlbumLibId::Value(8)), + date: SerdeAlbumDate(AlbumDate::new(Some(2018), None, None)), + seq: 0, + musicbrainz: DeserializeMbRefOption(MbRefOption::None), + primary_type: Some(SerdeAlbumPrimaryType(AlbumPrimaryType::Album)), + secondary_types: vec![], + }, + ], + ), + ( + String::from("Album_Artist ‘D’"), + vec![ + DeserializeAlbum { + title: String::from("album_title d.a"), + lib_id: SerdeAlbumLibId(AlbumLibId::Value(9)), + date: SerdeAlbumDate(AlbumDate::new(Some(1995), None, None)), + seq: 0, + musicbrainz: DeserializeMbRefOption(MbRefOption::None), + primary_type: Some(SerdeAlbumPrimaryType(AlbumPrimaryType::Album)), + secondary_types: vec![], + }, + DeserializeAlbum { + title: String::from("album_title d.b"), + lib_id: SerdeAlbumLibId(AlbumLibId::Value(10)), + date: SerdeAlbumDate(AlbumDate::new(Some(2028), None, None)), + seq: 0, + musicbrainz: DeserializeMbRefOption(MbRefOption::None), + primary_type: Some(SerdeAlbumPrimaryType(AlbumPrimaryType::Album)), + secondary_types: vec![], + }, + ], + ), + ]) +});