From c7bb43d8d65a797a99e516477e8d5cb7e32fcdc9 Mon Sep 17 00:00:00 2001 From: Abestanis Date: Mon, 26 Aug 2024 01:05:23 +0200 Subject: [PATCH 1/6] Add tests for sorting behaviour and make album year optional --- lib/localization/localization.dart | 8 - lib/logic/models/album.dart | 9 +- lib/logic/models/sort.dart | 212 +++++++----------- lib/logic/player/content.dart | 19 +- .../content_list_view/list_header.dart | 2 +- .../persistent_queue_tile.dart | 2 +- test/logic/models/sort_test.dart | 201 +++++++++++++++++ 7 files changed, 290 insertions(+), 163 deletions(-) create mode 100644 test/logic/models/sort_test.dart diff --git a/lib/localization/localization.dart b/lib/localization/localization.dart index 811fb145a..09537c1de 100644 --- a/lib/localization/localization.dart +++ b/lib/localization/localization.dart @@ -65,8 +65,6 @@ extension AppLocalizationsExtension on AppLocalizations { return artist; case SongSortFeature.album: return album; - default: - throw UnimplementedError(); } case ContentType.album: switch (feature as AlbumSortFeature) { @@ -78,8 +76,6 @@ extension AppLocalizationsExtension on AppLocalizations { return year; case AlbumSortFeature.numberOfSongs: return numberOfTracks; - default: - throw UnimplementedError(); } case ContentType.playlist: switch (feature as PlaylistSortFeature) { @@ -89,8 +85,6 @@ extension AppLocalizationsExtension on AppLocalizations { return dateAdded; case PlaylistSortFeature.name: return title; - default: - throw UnimplementedError(); } case ContentType.artist: switch (feature as ArtistSortFeature) { @@ -100,8 +94,6 @@ extension AppLocalizationsExtension on AppLocalizations { return numberOfAlbums; case ArtistSortFeature.numberOfTracks: return numberOfTracks; - default: - throw UnimplementedError(); } } } diff --git a/lib/logic/models/album.dart b/lib/logic/models/album.dart index d91b58787..3393e1cc2 100644 --- a/lib/logic/models/album.dart +++ b/lib/logic/models/album.dart @@ -37,8 +37,8 @@ class Album extends PersistentQueue implements PlatformAlbum { bool get playable => true; /// Gets album normalized year. - int get year { - return lastYear == null || lastYear! < 1000 ? clock.now().year : lastYear!; + int? get year { + return lastYear ?? firstYear; } /// Returns string in format `album name • year`. @@ -46,11 +46,6 @@ class Album extends PersistentQueue implements PlatformAlbum { return ContentUtils.appendYearWithDot(album, year); } - /// Returns string in format `Album • year`. - String albumDotName(AppLocalizations l10n) { - return ContentUtils.appendYearWithDot(l10n.album, year); - } - /// Returns the album artist. Artist? getArtist() => artistId == null ? null : ContentControl.instance.state.artists.firstWhereOrNull((el) => el.id == artistId); diff --git a/lib/logic/models/sort.dart b/lib/logic/models/sort.dart index 99b2c4558..f9ed7a35f 100644 --- a/lib/logic/models/sort.dart +++ b/lib/logic/models/sort.dart @@ -1,15 +1,19 @@ -import 'package:enum_to_string/enum_to_string.dart'; import 'package:equatable/equatable.dart'; import 'package:sweyer/sweyer.dart'; -/// Interface for other sort feature enums. -abstract class SortFeature extends Enum { - const SortFeature._(String value) : super(value); +/// The order of a sort operation. +enum SortOrder { + /// Ascending sort order ("lower" values first, "higher" values last). + ascending, + + /// Descending sort order ("higher" values first, "lower" values last). + descending, +} +/// Interface for other sort feature enums. +abstract class SortFeature { /// Returns sort feature values for a given content. static List> getValuesForContent(ContentType contentType) { - // TODO: Remove ContentType cast, see https://github.com/dart-lang/language/issues/2315 - // ignore: unnecessary_cast switch (contentType as ContentType) { case ContentType.song: return SongSortFeature.values as List>; @@ -22,120 +26,112 @@ abstract class SortFeature extends Enum { } } - /// Whether the default order is ASC. - bool get defaultOrderAscending; + /// An identifier for this feature. + String get id; + + /// The default sorting order of the feature. + SortOrder get defaultSortingOrder; } /// Features to sort by a [Song] list. /// /// Each feature also has the default sort order - ASC or DESC. /// When user changes the [SongSortFeature] the new default sort order is applied. -class SongSortFeature extends SortFeature { - const SongSortFeature._(String value) : super._(value); - - @override - bool get defaultOrderAscending => this != dateModified && this != dateAdded; - - static List get values => const [dateModified, dateAdded, title, artist, album]; - +enum SongSortFeature implements SortFeature { /// Sort by the [Song.dateModified]. - /// Default sort order is DESC. - static const dateModified = SongSortFeature._('dateModified'); + dateModified(SortOrder.descending), /// Sort by the [Song.dateAdded]. - /// Default sort order is DESC. - static const dateAdded = SongSortFeature._('dateAdded'); + dateAdded(SortOrder.descending), /// Sort by the [Song.title]. - /// Default sort order is ASC. - static const title = SongSortFeature._('title'); + title(SortOrder.ascending), /// Sort by the [Song.artist]. - /// Default sort order is ASC. - static const artist = SongSortFeature._('artist'); + artist(SortOrder.ascending), /// Sort by the [Song.album]. - /// Default sort order is ASC. - static const album = SongSortFeature._('album'); + album(SortOrder.ascending); + + const SongSortFeature(this.defaultSortingOrder); + + @override + String get id => name; + + @override + final SortOrder defaultSortingOrder; } /// Features to sort by a [Album] list. /// /// Each feature also has the default sort order - ASC or DESC. /// When user changes the [AlbumSortFeature] the new default sort order is applied. -class AlbumSortFeature extends SortFeature { - const AlbumSortFeature._(String value) : super._(value); - - @override - bool get defaultOrderAscending => this != year; - - static List get values => const [title, artist, year, numberOfSongs]; - +enum AlbumSortFeature implements SortFeature { /// Sort by the [Album.album]. - /// Default sort order is ASC. - static const title = AlbumSortFeature._('title'); + title(SortOrder.ascending), /// Sort by the [Album.artist]. - /// Default sort order is ASC. - static const artist = AlbumSortFeature._('artist'); + artist(SortOrder.ascending), /// Sort by the [Album.lastYear]. - /// Default sort order is DESC. - static const year = AlbumSortFeature._('year'); + year(SortOrder.descending), /// Sort by the [Album.numberOfSongs]. - /// Default sort order is ASC. - static const numberOfSongs = AlbumSortFeature._('numberOfSongs'); + numberOfSongs(SortOrder.ascending); + + const AlbumSortFeature(this.defaultSortingOrder); + + @override + String get id => name; + + @override + final SortOrder defaultSortingOrder; } /// Features to sort by a [Playlist] list. /// /// Each feature also has the default sort order - ASC or DESC. /// When user changes the [PlaylistSortFeature] the new default sort order is applied. -class PlaylistSortFeature extends SortFeature { - const PlaylistSortFeature._(String value) : super._(value); - - @override - bool get defaultOrderAscending => this != dateModified && this != dateAdded; - - static List get values => const [dateAdded, dateModified, name]; - +enum PlaylistSortFeature implements SortFeature { /// Sort by the [Playlist.dateModified]. - /// Default sort order is DESC. - static const dateModified = PlaylistSortFeature._('dateModified'); + dateModified(SortOrder.descending), /// Sort by the [Playlist.dateAdded]. - /// Default sort order is DESC. - static const dateAdded = PlaylistSortFeature._('dateAdded'); + dateAdded(SortOrder.descending), /// Sort by the [Playlist.name]. - /// Default sort order is ASC. - static const name = PlaylistSortFeature._('name'); + name(SortOrder.ascending); + + const PlaylistSortFeature(this.defaultSortingOrder); + + @override + String get id => this.name; + + @override + final SortOrder defaultSortingOrder; } /// Features to sort by a [Artist] list. /// /// Each feature also has the default sort order - ASC or DESC. /// When user changes the [ArtistSortFeature] the new default sort order is applied. -class ArtistSortFeature extends SortFeature { - const ArtistSortFeature._(String value) : super._(value); - - @override - bool get defaultOrderAscending => true; - - static List get values => const [name, numberOfAlbums, numberOfTracks]; - +enum ArtistSortFeature implements SortFeature { /// Sort by the [Artist.artist]. - /// Default sort order is ASC. - static const name = ArtistSortFeature._('name'); + name(SortOrder.ascending), /// Sort by the [Artist.numberOfAlbums]. - /// Default sort order is ASC. - static const numberOfAlbums = ArtistSortFeature._('numberOfAlbums'); + numberOfAlbums(SortOrder.ascending), /// Sort by the [Artist.numberOfTracks]. - /// Default sort order is ASC. - static const numberOfTracks = ArtistSortFeature._('numberOfTracks'); + numberOfTracks(SortOrder.ascending); + + const ArtistSortFeature(this.defaultSortingOrder); + + @override + String get id => this.name; + + @override + final SortOrder defaultSortingOrder; } abstract class Sort extends Equatable { @@ -143,7 +139,7 @@ abstract class Sort extends Equatable { required this.feature, required this.orderAscending, }); - Sort.defaultOrder(this.feature) : orderAscending = feature.defaultOrderAscending; + Sort.defaultOrder(this.feature) : orderAscending = feature.defaultSortingOrder == SortOrder.ascending; final SortFeature feature; final bool orderAscending; @@ -151,29 +147,26 @@ abstract class Sort extends Equatable { @override List get props => [feature, orderAscending]; - Sort copyWith({SortFeature? feature, bool? orderAscending}); - Sort get withDefaultOrder; + Sort copyWith({SortFeature? feature, bool? orderAscending}); + Sort get withDefaultOrder => copyWith(orderAscending: feature.defaultSortingOrder == SortOrder.ascending); Comparator get comparator; Map toMap() => { - 'feature': feature.value, + 'feature': feature.id, 'orderAscending': orderAscending, }; } class SongSort extends Sort { const SongSort({ - required SongSortFeature feature, - bool orderAscending = true, - }) : super(feature: feature, orderAscending: orderAscending); + required SongSortFeature super.feature, + super.orderAscending = true, + }); SongSort.defaultOrder(feature) : super.defaultOrder(feature); factory SongSort.fromMap(Map map) => SongSort( - feature: EnumToString.fromString( - SongSortFeature.values, - map['feature'], - )!, + feature: SongSortFeature.values.byName(map['feature']), orderAscending: map['orderAscending'], ); @@ -188,11 +181,6 @@ class SongSort extends Sort { ); } - @override - SongSort get withDefaultOrder { - return copyWith(orderAscending: feature.defaultOrderAscending); - } - int _fallbackTitle(Song a, Song b) { return a.title.toLowerCase().compareTo(b.title.toLowerCase()); } @@ -268,19 +256,10 @@ class AlbumSort extends Sort { AlbumSort.defaultOrder(feature) : super.defaultOrder(feature); factory AlbumSort.fromMap(Map map) => AlbumSort( - feature: EnumToString.fromString( - AlbumSortFeature.values, - map['feature'], - )!, + feature: AlbumSortFeature.values.byName(map['feature']), orderAscending: map['orderAscending'], ); - @override - Map toMap() => { - 'feature': feature.value, - 'orderAscending': orderAscending, - }; - @override AlbumSort copyWith({ covariant AlbumSortFeature? feature, @@ -292,13 +271,8 @@ class AlbumSort extends Sort { ); } - @override - AlbumSort get withDefaultOrder { - return copyWith(orderAscending: feature.defaultOrderAscending); - } - int _fallbackYear(Album a, Album b) { - return a.year.compareTo(b.year); + return (a.year ?? 0).compareTo((b.year ?? 0)); // TODO: Decide how to sort null values } int _fallbackTitle(Album a, Album b) { @@ -329,7 +303,7 @@ class AlbumSort extends Sort { break; case AlbumSortFeature.year: c = (a, b) { - final compare = a.year.compareTo(b.year); + final compare = (a.year ?? 0).compareTo(b.year ?? 0); // TODO: Decide how to sort null values if (compare == 0) { return _fallbackTitle(a, b); } @@ -363,19 +337,10 @@ class PlaylistSort extends Sort { PlaylistSort.defaultOrder(feature) : super.defaultOrder(feature); factory PlaylistSort.fromMap(Map map) => PlaylistSort( - feature: EnumToString.fromString( - PlaylistSortFeature.values, - map['feature'], - )!, + feature: PlaylistSortFeature.values.byName(map['feature']), orderAscending: map['orderAscending'], ); - @override - Map toMap() => { - 'feature': feature.value, - 'orderAscending': orderAscending, - }; - @override PlaylistSort copyWith({ covariant PlaylistSortFeature? feature, @@ -387,11 +352,6 @@ class PlaylistSort extends Sort { ); } - @override - PlaylistSort get withDefaultOrder { - return copyWith(orderAscending: feature.defaultOrderAscending); - } - int _fallbackName(Playlist a, Playlist b) { return a.name.toLowerCase().compareTo(b.name.toLowerCase()); } @@ -449,19 +409,10 @@ class ArtistSort extends Sort { ArtistSort.defaultOrder(feature) : super.defaultOrder(feature); factory ArtistSort.fromMap(Map map) => ArtistSort( - feature: EnumToString.fromString( - ArtistSortFeature.values, - map['feature'], - )!, + feature: ArtistSortFeature.values.byName(map['feature']), orderAscending: map['orderAscending'], ); - @override - Map toMap() => { - 'feature': feature.value, - 'orderAscending': orderAscending, - }; - @override ArtistSort copyWith({ covariant ArtistSortFeature? feature, @@ -473,11 +424,6 @@ class ArtistSort extends Sort { ); } - @override - ArtistSort get withDefaultOrder { - return copyWith(orderAscending: feature.defaultOrderAscending); - } - int _fallbackName(Artist a, Artist b) { return a.artist.toLowerCase().compareTo(b.artist.toLowerCase()); } diff --git a/lib/logic/player/content.dart b/lib/logic/player/content.dart index ebbfbddf2..6fca5538d 100644 --- a/lib/logic/player/content.dart +++ b/lib/logic/player/content.dart @@ -822,18 +822,8 @@ class ContentUtils { static const String dot = '•'; /// Joins list with the [dot]. - static String joinDot(List list) { - if (list.isEmpty) { - return ''; - } - var result = list.first; - for (int i = 1; i < list.length; i++) { - final string = list[i].toString(); - if (string.isNotEmpty) { - result += ' $dot $string'; - } - } - return result; + static String joinDot(List list) { + return list.where((item) => item != null && item.toString().isNotEmpty).join(' $dot '); } /// Returns a default icon for the playlist art. @@ -855,7 +845,10 @@ class ContentUtils { } /// Appends dot and year to [string]. - static String appendYearWithDot(String string, int year) { + static String appendYearWithDot(String string, int? year) { + if (year == null) { + return string; + } return '$string $dot $year'; } diff --git a/lib/widgets/content_list_view/list_header.dart b/lib/widgets/content_list_view/list_header.dart index a2a7a4b47..b91e04cb7 100644 --- a/lib/widgets/content_list_view/list_header.dart +++ b/lib/widgets/content_list_view/list_header.dart @@ -108,7 +108,7 @@ class ContentListHeader extends StatelessWidget { void _handleTap(BuildContext context) { final l10n = getl10n(context); final sort = getSort(); - ShowFunctions.instance.showRadio( + ShowFunctions.instance.showRadio>( context: context, title: l10n.sort, items: SortFeature.getValuesForContent(contentType), diff --git a/lib/widgets/content_list_view/persistent_queue_tile.dart b/lib/widgets/content_list_view/persistent_queue_tile.dart index b9435060a..331fed3d2 100644 --- a/lib/widgets/content_list_view/persistent_queue_tile.dart +++ b/lib/widgets/content_list_view/persistent_queue_tile.dart @@ -230,7 +230,7 @@ class _PersistentQueueTileState if (queue is Album) { children.add(ArtistWidget( artist: queue.artist, - trailingText: queue.year.toString(), + trailingText: queue.year?.toString(), textStyle: _subtitleTheme(widget.queue.type, theme), )); } else if (queue is Playlist) { diff --git a/test/logic/models/sort_test.dart b/test/logic/models/sort_test.dart new file mode 100644 index 000000000..d4e4cca99 --- /dev/null +++ b/test/logic/models/sort_test.dart @@ -0,0 +1,201 @@ +import '../../test.dart'; + +void main() { + group('Song sorting', () { + late List songs; + setUp(() { + songs = [ + songWith(id: 0, dateModified: 0, dateAdded: 0, title: '', artist: '', album: ''), + songWith(id: 1, dateModified: 1, dateAdded: 0, title: '', artist: '', album: ''), + songWith(id: 2, dateModified: -1, dateAdded: 0, title: '', artist: '', album: ''), + songWith(id: 3, dateModified: 0, dateAdded: 1, title: '', artist: '', album: ''), + songWith(id: 4, dateModified: 0, dateAdded: -1, title: '', artist: '', album: ''), + songWith(id: 5, dateModified: 0, dateAdded: 0, title: 'A', artist: '', album: ''), + songWith(id: 6, dateModified: 0, dateAdded: 0, title: 'AA', artist: '', album: ''), + songWith(id: 7, dateModified: 0, dateAdded: 0, title: 'a', artist: '', album: ''), + songWith(id: 8, dateModified: 0, dateAdded: 0, title: 'z', artist: '', album: ''), + songWith(id: 9, dateModified: 0, dateAdded: 0, title: '', artist: 'A', album: ''), + songWith(id: 10, dateModified: 0, dateAdded: 0, title: '', artist: 'AA', album: ''), + songWith(id: 11, dateModified: 0, dateAdded: 0, title: '', artist: 'a', album: ''), + songWith(id: 12, dateModified: 0, dateAdded: 0, title: '', artist: 'z', album: ''), + songWith(id: 13, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'A'), + songWith(id: 14, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'AA'), + songWith(id: 15, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'a'), + songWith(id: 16, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'z'), + ]; + }); + final Map>> testCases = { + SortOrder.ascending: { + SongSortFeature.dateModified: [2, 0, 3, 4, 9, 10, 11, 12, 13, 14, 15, 16, 5, 7, 6, 8, 1], + SongSortFeature.dateAdded: [4, 0, 1, 2, 9, 10, 11, 12, 13, 14, 15, 16, 5, 7, 6, 8, 3], + SongSortFeature.title: [2, 0, 3, 4, 9, 10, 11, 12, 13, 14, 15, 16, 1, 5, 7, 6, 8], + SongSortFeature.artist: [0, 1, 2, 3, 4, 13, 14, 15, 16, 5, 7, 6, 8, 9, 11, 10, 12], + SongSortFeature.album: [0, 1, 2, 3, 4, 9, 10, 11, 12, 5, 7, 6, 8, 13, 15, 14, 16], + }, + SortOrder.descending: { + SongSortFeature.dateModified: [1, 8, 6, 5, 7, 0, 3, 4, 9, 10, 11, 12, 13, 14, 15, 16, 2], + SongSortFeature.dateAdded: [3, 8, 6, 5, 7, 0, 1, 2, 9, 10, 11, 12, 13, 14, 15, 16, 4], + SongSortFeature.title: [8, 6, 5, 7, 1, 0, 3, 4, 9, 10, 11, 12, 13, 14, 15, 16, 2], + SongSortFeature.artist: [12, 10, 9, 11, 8, 6, 5, 7, 0, 1, 2, 3, 4, 13, 14, 15, 16], + SongSortFeature.album: [16, 14, 13, 15, 8, 6, 5, 7, 0, 1, 2, 3, 4, 9, 10, 11, 12], + }, + }; + for (final entry in testCases.entries) { + final sortOrder = entry.key; + final featureTestCases = entry.value; + for (final entry in featureTestCases.entries) { + final feature = entry.key; + final expectedContentList = entry.value; + test('Sorts songs by ${feature.name} ${sortOrder.name}', () async { + expect( + songs.toList() + ..sort(SongSort(feature: feature, orderAscending: sortOrder == SortOrder.ascending).comparator), + expectedContentList.map((i) => songs[i]).toList(), + ); + }); + } + } + }); + + group('Album sorting', () { + late List albums; + setUp(() { + albums = [ + albumWith(id: 0, album: '', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 1, album: 'A', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 2, album: 'AA', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 3, album: 'a', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 4, album: 'z', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 5, album: '', artist: 'A', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 6, album: '', artist: 'AA', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 7, album: '', artist: 'a', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 8, album: '', artist: 'z', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 9, album: '', artist: '', lastYear: 1, firstYear: 0, numberOfSongs: 0), + albumWith(id: 10, album: '', artist: '', lastYear: -1, firstYear: 0, numberOfSongs: 0), + albumWith(id: 11, album: '', artist: '', lastYear: null, firstYear: 0, numberOfSongs: 0), + albumWith(id: 12, album: '', artist: '', lastYear: null, firstYear: 1, numberOfSongs: 0), + albumWith(id: 13, album: '', artist: '', lastYear: null, firstYear: -1, numberOfSongs: 0), + albumWith(id: 14, album: '', artist: '', lastYear: null, firstYear: null, numberOfSongs: 0), + albumWith(id: 15, album: '', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 1), + albumWith(id: 16, album: '', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: -1), + ]; + }); + final Map>> testCases = { + SortOrder.ascending: { + AlbumSortFeature.title: [10, 13, 0, 5, 6, 7, 8, 11, 14, 15, 16, 9, 12, 1, 3, 2, 4], + AlbumSortFeature.artist: [10, 13, 0, 1, 2, 3, 4, 11, 14, 15, 16, 9, 12, 5, 7, 6, 8], + AlbumSortFeature.year: [10, 13, 0, 5, 6, 7, 8, 11, 14, 15, 16, 1, 3, 2, 4, 9, 12], + AlbumSortFeature.numberOfSongs: [16, 10, 13, 0, 1, 2, 3, 4, 5, 6, 7, 8, 11, 14, 9, 12, 15], + }, + SortOrder.descending: { + AlbumSortFeature.title: [4, 2, 1, 3, 9, 12, 0, 5, 6, 7, 8, 11, 14, 15, 16, 10, 13], + AlbumSortFeature.artist: [8, 6, 5, 7, 9, 12, 0, 1, 2, 3, 4, 11, 14, 15, 16, 10, 13], + AlbumSortFeature.year: [9, 12, 4, 2, 1, 3, 0, 5, 6, 7, 8, 11, 14, 15, 16, 10, 13], + AlbumSortFeature.numberOfSongs: [15, 9, 12, 0, 1, 2, 3, 4, 5, 6, 7, 8, 11, 14, 10, 13, 16], + }, + }; + for (final entry in testCases.entries) { + final sortOrder = entry.key; + final featureTestCases = entry.value; + for (final entry in featureTestCases.entries) { + final feature = entry.key; + final expectedContentList = entry.value; + test('Sorts albums by ${feature.name} ${sortOrder.name}', () async { + expect( + albums.toList() + ..sort(AlbumSort(feature: feature, orderAscending: sortOrder == SortOrder.ascending).comparator), + expectedContentList.map((i) => albums[i]).toList(), + ); + }); + } + } + }); + + group('Playlist sorting', () { + late List playlists; + setUp(() { + playlists = [ + playlistWith(id: 0, name: '', dateModified: 0, dateAdded: 0), + playlistWith(id: 1, name: 'A', dateModified: 0, dateAdded: 0), + playlistWith(id: 2, name: 'AA', dateModified: 0, dateAdded: 0), + playlistWith(id: 3, name: 'a', dateModified: 0, dateAdded: 0), + playlistWith(id: 4, name: 'z', dateModified: 0, dateAdded: 0), + playlistWith(id: 5, name: '', dateModified: 1, dateAdded: 0), + playlistWith(id: 6, name: '', dateModified: -1, dateAdded: 0), + playlistWith(id: 7, name: '', dateModified: 0, dateAdded: 1), + playlistWith(id: 8, name: '', dateModified: 0, dateAdded: -1), + ]; + }); + final Map>> testCases = { + SortOrder.ascending: { + PlaylistSortFeature.dateModified: [6, 0, 7, 8, 1, 3, 2, 4, 5], + PlaylistSortFeature.dateAdded: [8, 0, 5, 6, 1, 3, 2, 4, 7], + PlaylistSortFeature.name: [6, 0, 7, 8, 5, 1, 3, 2, 4], + }, + SortOrder.descending: { + PlaylistSortFeature.dateModified: [5, 4, 2, 1, 3, 0, 7, 8, 6], + PlaylistSortFeature.dateAdded: [7, 4, 2, 1, 3, 0, 5, 6, 8], + PlaylistSortFeature.name: [4, 2, 1, 3, 5, 0, 7, 8, 6], + }, + }; + for (final entry in testCases.entries) { + final sortOrder = entry.key; + final featureTestCases = entry.value; + for (final entry in featureTestCases.entries) { + final feature = entry.key; + final expectedContentList = entry.value; + test('Sorts playlists by ${feature.name} ${sortOrder.name}', () async { + expect( + playlists.toList() + ..sort(PlaylistSort(feature: feature, orderAscending: sortOrder == SortOrder.ascending).comparator), + expectedContentList.map((i) => playlists[i]).toList(), + ); + }); + } + } + }); + + group('Artist sorting', () { + late List artists; + setUp(() { + artists = [ + artistWith(id: 0, artist: '', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 1, artist: 'A', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 2, artist: 'AA', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 3, artist: 'a', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 4, artist: 'z', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 5, artist: '', numberOfAlbums: 1, numberOfTracks: 0), + artistWith(id: 6, artist: '', numberOfAlbums: -1, numberOfTracks: 0), + artistWith(id: 7, artist: '', numberOfAlbums: 0, numberOfTracks: 1), + artistWith(id: 8, artist: '', numberOfAlbums: 0, numberOfTracks: -1), + ]; + }); + final Map>> testCases = { + SortOrder.ascending: { + ArtistSortFeature.name: [8, 0, 5, 6, 7, 1, 3, 2, 4], + ArtistSortFeature.numberOfAlbums: [6, 0, 7, 8, 1, 3, 2, 4, 5], + ArtistSortFeature.numberOfTracks: [8, 0, 5, 6, 1, 3, 2, 4, 7], + }, + SortOrder.descending: { + ArtistSortFeature.name: [4, 2, 1, 3, 7, 0, 5, 6, 8], + ArtistSortFeature.numberOfAlbums: [5, 4, 2, 1, 3, 0, 7, 8, 6], + ArtistSortFeature.numberOfTracks: [7, 4, 2, 1, 3, 0, 5, 6, 8], + }, + }; + for (final entry in testCases.entries) { + final sortOrder = entry.key; + final featureTestCases = entry.value; + for (final entry in featureTestCases.entries) { + final feature = entry.key; + final expectedContentList = entry.value; + test('Sorts artists by ${feature.name} ${sortOrder.name}', () async { + expect( + artists.toList() + ..sort(ArtistSort(feature: feature, orderAscending: sortOrder == SortOrder.ascending).comparator), + expectedContentList.map((i) => artists[i]).toList(), + ); + }); + } + } + }); +} From 94cad8f0b99b5fddc36f5254d1243b0e9ae49191 Mon Sep 17 00:00:00 2001 From: Abestanis Date: Mon, 14 Oct 2024 11:58:00 +0200 Subject: [PATCH 2/6] Mark SortFeature as an interface --- lib/logic/models/sort.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/logic/models/sort.dart b/lib/logic/models/sort.dart index f9ed7a35f..e11f23c15 100644 --- a/lib/logic/models/sort.dart +++ b/lib/logic/models/sort.dart @@ -11,7 +11,7 @@ enum SortOrder { } /// Interface for other sort feature enums. -abstract class SortFeature { +abstract interface class SortFeature { /// Returns sort feature values for a given content. static List> getValuesForContent(ContentType contentType) { switch (contentType as ContentType) { From eaa7c75b7ef766233cf9767646252be7cb539cb4 Mon Sep 17 00:00:00 2001 From: Abestanis Date: Mon, 14 Oct 2024 12:15:23 +0200 Subject: [PATCH 3/6] Use SortOrder in Sort --- lib/logic/models/sort.dart | 76 ++++++++++--------- .../content_list_view/list_header.dart | 4 +- test/logic/models/sort_test.dart | 12 +-- 3 files changed, 47 insertions(+), 45 deletions(-) diff --git a/lib/logic/models/sort.dart b/lib/logic/models/sort.dart index e11f23c15..ca3f75209 100644 --- a/lib/logic/models/sort.dart +++ b/lib/logic/models/sort.dart @@ -7,7 +7,13 @@ enum SortOrder { ascending, /// Descending sort order ("higher" values first, "lower" values last). - descending, + descending; + + /// The inversion of the sort order. + SortOrder get inverted => switch (this) { + SortOrder.ascending => SortOrder.descending, + SortOrder.descending => SortOrder.ascending, + }; } /// Interface for other sort feature enums. @@ -137,47 +143,47 @@ enum ArtistSortFeature implements SortFeature { abstract class Sort extends Equatable { const Sort({ required this.feature, - required this.orderAscending, + required this.order, }); - Sort.defaultOrder(this.feature) : orderAscending = feature.defaultSortingOrder == SortOrder.ascending; + Sort.defaultOrder(this.feature) : order = feature.defaultSortingOrder; final SortFeature feature; - final bool orderAscending; + final SortOrder order; @override - List get props => [feature, orderAscending]; + List get props => [feature, order]; - Sort copyWith({SortFeature? feature, bool? orderAscending}); - Sort get withDefaultOrder => copyWith(orderAscending: feature.defaultSortingOrder == SortOrder.ascending); + Sort copyWith({SortFeature? feature, SortOrder? order}); + Sort get withDefaultOrder => copyWith(order: feature.defaultSortingOrder); Comparator get comparator; Map toMap() => { 'feature': feature.id, - 'orderAscending': orderAscending, + 'order': order, }; } class SongSort extends Sort { const SongSort({ - required SongSortFeature super.feature, - super.orderAscending = true, + required super.feature, + super.order = SortOrder.ascending, }); SongSort.defaultOrder(feature) : super.defaultOrder(feature); factory SongSort.fromMap(Map map) => SongSort( feature: SongSortFeature.values.byName(map['feature']), - orderAscending: map['orderAscending'], + order: SortOrder.values.byName(map['order'] ?? 'ascending'), ); @override SongSort copyWith({ covariant SongSortFeature? feature, - bool? orderAscending, + SortOrder? order, }) { return SongSort( feature: feature ?? this.feature as SongSortFeature, - orderAscending: orderAscending ?? this.orderAscending, + order: order ?? this.order, ); } @@ -241,7 +247,7 @@ class SongSort extends Sort { default: throw UnimplementedError(); } - if (!orderAscending) { + if (order == SortOrder.descending) { return (a, b) => c(b, a); } return c; @@ -250,24 +256,24 @@ class SongSort extends Sort { class AlbumSort extends Sort { const AlbumSort({ - required AlbumSortFeature feature, - bool orderAscending = true, - }) : super(feature: feature, orderAscending: orderAscending); + required super.feature, + super.order = SortOrder.ascending, + }); AlbumSort.defaultOrder(feature) : super.defaultOrder(feature); factory AlbumSort.fromMap(Map map) => AlbumSort( feature: AlbumSortFeature.values.byName(map['feature']), - orderAscending: map['orderAscending'], + order: SortOrder.values.byName(map['order'] ?? 'ascending'), ); @override AlbumSort copyWith({ covariant AlbumSortFeature? feature, - bool? orderAscending, + SortOrder? order, }) { return AlbumSort( feature: feature ?? this.feature as AlbumSortFeature, - orderAscending: orderAscending ?? this.orderAscending, + order: order ?? this.order, ); } @@ -322,7 +328,7 @@ class AlbumSort extends Sort { default: throw UnimplementedError(); } - if (!orderAscending) { + if (order == SortOrder.descending) { return (a, b) => c(b, a); } return c; @@ -331,24 +337,24 @@ class AlbumSort extends Sort { class PlaylistSort extends Sort { const PlaylistSort({ - required PlaylistSortFeature feature, - bool orderAscending = true, - }) : super(feature: feature, orderAscending: orderAscending); + required super.feature, + super.order = SortOrder.ascending, + }); PlaylistSort.defaultOrder(feature) : super.defaultOrder(feature); factory PlaylistSort.fromMap(Map map) => PlaylistSort( feature: PlaylistSortFeature.values.byName(map['feature']), - orderAscending: map['orderAscending'], + order: SortOrder.values.byName(map['order'] ?? 'ascending'), ); @override PlaylistSort copyWith({ covariant PlaylistSortFeature? feature, - bool? orderAscending, + SortOrder? order, }) { return PlaylistSort( feature: feature ?? this.feature as PlaylistSortFeature, - orderAscending: orderAscending ?? this.orderAscending, + order: order ?? this.order, ); } @@ -394,7 +400,7 @@ class PlaylistSort extends Sort { default: throw UnimplementedError(); } - if (!orderAscending) { + if (order == SortOrder.descending) { return (a, b) => c(b, a); } return c; @@ -403,24 +409,24 @@ class PlaylistSort extends Sort { class ArtistSort extends Sort { const ArtistSort({ - required ArtistSortFeature feature, - bool orderAscending = true, - }) : super(feature: feature, orderAscending: orderAscending); + required super.feature, + super.order = SortOrder.ascending, + }); ArtistSort.defaultOrder(feature) : super.defaultOrder(feature); factory ArtistSort.fromMap(Map map) => ArtistSort( feature: ArtistSortFeature.values.byName(map['feature']), - orderAscending: map['orderAscending'], + order: SortOrder.values.byName(map['order'] ?? 'ascending'), ); @override ArtistSort copyWith({ covariant ArtistSortFeature? feature, - bool? orderAscending, + SortOrder? order, }) { return ArtistSort( feature: feature ?? this.feature as ArtistSortFeature, - orderAscending: orderAscending ?? this.orderAscending, + order: order ?? this.order, ); } @@ -466,7 +472,7 @@ class ArtistSort extends Sort { default: throw UnimplementedError(); } - if (!orderAscending) { + if (order == SortOrder.descending) { return (a, b) => c(b, a); } return c; diff --git a/lib/widgets/content_list_view/list_header.dart b/lib/widgets/content_list_view/list_header.dart index b91e04cb7..d6156424f 100644 --- a/lib/widgets/content_list_view/list_header.dart +++ b/lib/widgets/content_list_view/list_header.dart @@ -174,11 +174,11 @@ class ContentListHeader extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.start, children: [ ContentListHeaderAction( - icon: Icon(sort.orderAscending ? Icons.north_rounded : Icons.south_rounded), + icon: Icon(sort.order == SortOrder.ascending ? Icons.north_rounded : Icons.south_rounded), onPressed: () { ContentControl.instance.sort( contentType: contentType, - sort: sort.copyWith(orderAscending: !sort.orderAscending), + sort: sort.copyWith(order: sort.order.inverted), ); }, ), diff --git a/test/logic/models/sort_test.dart b/test/logic/models/sort_test.dart index d4e4cca99..857c3bd97 100644 --- a/test/logic/models/sort_test.dart +++ b/test/logic/models/sort_test.dart @@ -48,8 +48,7 @@ void main() { final expectedContentList = entry.value; test('Sorts songs by ${feature.name} ${sortOrder.name}', () async { expect( - songs.toList() - ..sort(SongSort(feature: feature, orderAscending: sortOrder == SortOrder.ascending).comparator), + songs.toList()..sort(SongSort(feature: feature, order: sortOrder).comparator), expectedContentList.map((i) => songs[i]).toList(), ); }); @@ -102,8 +101,7 @@ void main() { final expectedContentList = entry.value; test('Sorts albums by ${feature.name} ${sortOrder.name}', () async { expect( - albums.toList() - ..sort(AlbumSort(feature: feature, orderAscending: sortOrder == SortOrder.ascending).comparator), + albums.toList()..sort(AlbumSort(feature: feature, order: sortOrder).comparator), expectedContentList.map((i) => albums[i]).toList(), ); }); @@ -146,8 +144,7 @@ void main() { final expectedContentList = entry.value; test('Sorts playlists by ${feature.name} ${sortOrder.name}', () async { expect( - playlists.toList() - ..sort(PlaylistSort(feature: feature, orderAscending: sortOrder == SortOrder.ascending).comparator), + playlists.toList()..sort(PlaylistSort(feature: feature, order: sortOrder).comparator), expectedContentList.map((i) => playlists[i]).toList(), ); }); @@ -190,8 +187,7 @@ void main() { final expectedContentList = entry.value; test('Sorts artists by ${feature.name} ${sortOrder.name}', () async { expect( - artists.toList() - ..sort(ArtistSort(feature: feature, orderAscending: sortOrder == SortOrder.ascending).comparator), + artists.toList()..sort(ArtistSort(feature: feature, order: sortOrder).comparator), expectedContentList.map((i) => artists[i]).toList(), ); }); From cb6ba2f4be27fbaeac0ac8be4e985e4eaf370e2c Mon Sep 17 00:00:00 2001 From: Abestanis Date: Mon, 14 Oct 2024 12:16:07 +0200 Subject: [PATCH 4/6] Use Dart 3 pattern destructuring in sort tests --- test/logic/models/sort_test.dart | 32 ++++++++------------------------ 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/test/logic/models/sort_test.dart b/test/logic/models/sort_test.dart index 857c3bd97..a80cacb39 100644 --- a/test/logic/models/sort_test.dart +++ b/test/logic/models/sort_test.dart @@ -40,12 +40,8 @@ void main() { SongSortFeature.album: [16, 14, 13, 15, 8, 6, 5, 7, 0, 1, 2, 3, 4, 9, 10, 11, 12], }, }; - for (final entry in testCases.entries) { - final sortOrder = entry.key; - final featureTestCases = entry.value; - for (final entry in featureTestCases.entries) { - final feature = entry.key; - final expectedContentList = entry.value; + for (final MapEntry(key: sortOrder, value: featureTestCases) in testCases.entries) { + for (final MapEntry(key: feature, value: expectedContentList) in featureTestCases.entries) { test('Sorts songs by ${feature.name} ${sortOrder.name}', () async { expect( songs.toList()..sort(SongSort(feature: feature, order: sortOrder).comparator), @@ -93,12 +89,8 @@ void main() { AlbumSortFeature.numberOfSongs: [15, 9, 12, 0, 1, 2, 3, 4, 5, 6, 7, 8, 11, 14, 10, 13, 16], }, }; - for (final entry in testCases.entries) { - final sortOrder = entry.key; - final featureTestCases = entry.value; - for (final entry in featureTestCases.entries) { - final feature = entry.key; - final expectedContentList = entry.value; + for (final MapEntry(key: sortOrder, value: featureTestCases) in testCases.entries) { + for (final MapEntry(key: feature, value: expectedContentList) in featureTestCases.entries) { test('Sorts albums by ${feature.name} ${sortOrder.name}', () async { expect( albums.toList()..sort(AlbumSort(feature: feature, order: sortOrder).comparator), @@ -136,12 +128,8 @@ void main() { PlaylistSortFeature.name: [4, 2, 1, 3, 5, 0, 7, 8, 6], }, }; - for (final entry in testCases.entries) { - final sortOrder = entry.key; - final featureTestCases = entry.value; - for (final entry in featureTestCases.entries) { - final feature = entry.key; - final expectedContentList = entry.value; + for (final MapEntry(key: sortOrder, value: featureTestCases) in testCases.entries) { + for (final MapEntry(key: feature, value: expectedContentList) in featureTestCases.entries) { test('Sorts playlists by ${feature.name} ${sortOrder.name}', () async { expect( playlists.toList()..sort(PlaylistSort(feature: feature, order: sortOrder).comparator), @@ -179,12 +167,8 @@ void main() { ArtistSortFeature.numberOfTracks: [7, 4, 2, 1, 3, 0, 5, 6, 8], }, }; - for (final entry in testCases.entries) { - final sortOrder = entry.key; - final featureTestCases = entry.value; - for (final entry in featureTestCases.entries) { - final feature = entry.key; - final expectedContentList = entry.value; + for (final MapEntry(key: sortOrder, value: featureTestCases) in testCases.entries) { + for (final MapEntry(key: feature, value: expectedContentList) in featureTestCases.entries) { test('Sorts artists by ${feature.name} ${sortOrder.name}', () async { expect( artists.toList()..sort(ArtistSort(feature: feature, order: sortOrder).comparator), From dd45d20c66d58b554e5cd37012baa3b5c9257f01 Mon Sep 17 00:00:00 2001 From: Abestanis Date: Mon, 14 Oct 2024 12:43:28 +0200 Subject: [PATCH 5/6] Make the sort expectation clearer to see in the tests --- test/logic/models/sort_test.dart | 536 ++++++++++++++++++++++++++++--- 1 file changed, 494 insertions(+), 42 deletions(-) diff --git a/test/logic/models/sort_test.dart b/test/logic/models/sort_test.dart index a80cacb39..258384f76 100644 --- a/test/logic/models/sort_test.dart +++ b/test/logic/models/sort_test.dart @@ -24,28 +24,210 @@ void main() { songWith(id: 16, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'z'), ]; }); - final Map>> testCases = { + final Map>> testCases = { SortOrder.ascending: { - SongSortFeature.dateModified: [2, 0, 3, 4, 9, 10, 11, 12, 13, 14, 15, 16, 5, 7, 6, 8, 1], - SongSortFeature.dateAdded: [4, 0, 1, 2, 9, 10, 11, 12, 13, 14, 15, 16, 5, 7, 6, 8, 3], - SongSortFeature.title: [2, 0, 3, 4, 9, 10, 11, 12, 13, 14, 15, 16, 1, 5, 7, 6, 8], - SongSortFeature.artist: [0, 1, 2, 3, 4, 13, 14, 15, 16, 5, 7, 6, 8, 9, 11, 10, 12], - SongSortFeature.album: [0, 1, 2, 3, 4, 9, 10, 11, 12, 5, 7, 6, 8, 13, 15, 14, 16], + SongSortFeature.dateModified: [ + songWith(id: 2, dateModified: -1, dateAdded: 0, title: '', artist: '', album: ''), + songWith(id: 0, dateModified: 0, dateAdded: 0, title: '', artist: '', album: ''), + songWith(id: 3, dateModified: 0, dateAdded: 1, title: '', artist: '', album: ''), + songWith(id: 4, dateModified: 0, dateAdded: -1, title: '', artist: '', album: ''), + songWith(id: 9, dateModified: 0, dateAdded: 0, title: '', artist: 'A', album: ''), + songWith(id: 10, dateModified: 0, dateAdded: 0, title: '', artist: 'AA', album: ''), + songWith(id: 11, dateModified: 0, dateAdded: 0, title: '', artist: 'a', album: ''), + songWith(id: 12, dateModified: 0, dateAdded: 0, title: '', artist: 'z', album: ''), + songWith(id: 13, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'A'), + songWith(id: 14, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'AA'), + songWith(id: 15, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'a'), + songWith(id: 16, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'z'), + songWith(id: 5, dateModified: 0, dateAdded: 0, title: 'A', artist: '', album: ''), + songWith(id: 7, dateModified: 0, dateAdded: 0, title: 'a', artist: '', album: ''), + songWith(id: 6, dateModified: 0, dateAdded: 0, title: 'AA', artist: '', album: ''), + songWith(id: 8, dateModified: 0, dateAdded: 0, title: 'z', artist: '', album: ''), + songWith(id: 1, dateModified: 1, dateAdded: 0, title: '', artist: '', album: ''), + ], + SongSortFeature.dateAdded: [ + songWith(id: 4, dateModified: 0, dateAdded: -1, title: '', artist: '', album: ''), + songWith(id: 0, dateModified: 0, dateAdded: 0, title: '', artist: '', album: ''), + songWith(id: 1, dateModified: 1, dateAdded: 0, title: '', artist: '', album: ''), + songWith(id: 2, dateModified: -1, dateAdded: 0, title: '', artist: '', album: ''), + songWith(id: 9, dateModified: 0, dateAdded: 0, title: '', artist: 'A', album: ''), + songWith(id: 10, dateModified: 0, dateAdded: 0, title: '', artist: 'AA', album: ''), + songWith(id: 11, dateModified: 0, dateAdded: 0, title: '', artist: 'a', album: ''), + songWith(id: 12, dateModified: 0, dateAdded: 0, title: '', artist: 'z', album: ''), + songWith(id: 13, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'A'), + songWith(id: 14, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'AA'), + songWith(id: 15, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'a'), + songWith(id: 16, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'z'), + songWith(id: 5, dateModified: 0, dateAdded: 0, title: 'A', artist: '', album: ''), + songWith(id: 7, dateModified: 0, dateAdded: 0, title: 'a', artist: '', album: ''), + songWith(id: 6, dateModified: 0, dateAdded: 0, title: 'AA', artist: '', album: ''), + songWith(id: 8, dateModified: 0, dateAdded: 0, title: 'z', artist: '', album: ''), + songWith(id: 3, dateModified: 0, dateAdded: 1, title: '', artist: '', album: ''), + ], + SongSortFeature.title: [ + songWith(id: 2, dateModified: -1, dateAdded: 0, title: '', artist: '', album: ''), + songWith(id: 0, dateModified: 0, dateAdded: 0, title: '', artist: '', album: ''), + songWith(id: 3, dateModified: 0, dateAdded: 1, title: '', artist: '', album: ''), + songWith(id: 4, dateModified: 0, dateAdded: -1, title: '', artist: '', album: ''), + songWith(id: 9, dateModified: 0, dateAdded: 0, title: '', artist: 'A', album: ''), + songWith(id: 10, dateModified: 0, dateAdded: 0, title: '', artist: 'AA', album: ''), + songWith(id: 11, dateModified: 0, dateAdded: 0, title: '', artist: 'a', album: ''), + songWith(id: 12, dateModified: 0, dateAdded: 0, title: '', artist: 'z', album: ''), + songWith(id: 13, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'A'), + songWith(id: 14, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'AA'), + songWith(id: 15, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'a'), + songWith(id: 16, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'z'), + songWith(id: 1, dateModified: 1, dateAdded: 0, title: '', artist: '', album: ''), + songWith(id: 5, dateModified: 0, dateAdded: 0, title: 'A', artist: '', album: ''), + songWith(id: 7, dateModified: 0, dateAdded: 0, title: 'a', artist: '', album: ''), + songWith(id: 6, dateModified: 0, dateAdded: 0, title: 'AA', artist: '', album: ''), + songWith(id: 8, dateModified: 0, dateAdded: 0, title: 'z', artist: '', album: ''), + ], + SongSortFeature.artist: [ + songWith(id: 0, dateModified: 0, dateAdded: 0, title: '', artist: '', album: ''), + songWith(id: 1, dateModified: 1, dateAdded: 0, title: '', artist: '', album: ''), + songWith(id: 2, dateModified: -1, dateAdded: 0, title: '', artist: '', album: ''), + songWith(id: 3, dateModified: 0, dateAdded: 1, title: '', artist: '', album: ''), + songWith(id: 4, dateModified: 0, dateAdded: -1, title: '', artist: '', album: ''), + songWith(id: 13, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'A'), + songWith(id: 14, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'AA'), + songWith(id: 15, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'a'), + songWith(id: 16, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'z'), + songWith(id: 5, dateModified: 0, dateAdded: 0, title: 'A', artist: '', album: ''), + songWith(id: 7, dateModified: 0, dateAdded: 0, title: 'a', artist: '', album: ''), + songWith(id: 6, dateModified: 0, dateAdded: 0, title: 'AA', artist: '', album: ''), + songWith(id: 8, dateModified: 0, dateAdded: 0, title: 'z', artist: '', album: ''), + songWith(id: 9, dateModified: 0, dateAdded: 0, title: '', artist: 'A', album: ''), + songWith(id: 11, dateModified: 0, dateAdded: 0, title: '', artist: 'a', album: ''), + songWith(id: 10, dateModified: 0, dateAdded: 0, title: '', artist: 'AA', album: ''), + songWith(id: 12, dateModified: 0, dateAdded: 0, title: '', artist: 'z', album: ''), + ], + SongSortFeature.album: [ + songWith(id: 0, dateModified: 0, dateAdded: 0, title: '', artist: '', album: ''), + songWith(id: 1, dateModified: 1, dateAdded: 0, title: '', artist: '', album: ''), + songWith(id: 2, dateModified: -1, dateAdded: 0, title: '', artist: '', album: ''), + songWith(id: 3, dateModified: 0, dateAdded: 1, title: '', artist: '', album: ''), + songWith(id: 4, dateModified: 0, dateAdded: -1, title: '', artist: '', album: ''), + songWith(id: 9, dateModified: 0, dateAdded: 0, title: '', artist: 'A', album: ''), + songWith(id: 10, dateModified: 0, dateAdded: 0, title: '', artist: 'AA', album: ''), + songWith(id: 11, dateModified: 0, dateAdded: 0, title: '', artist: 'a', album: ''), + songWith(id: 12, dateModified: 0, dateAdded: 0, title: '', artist: 'z', album: ''), + songWith(id: 5, dateModified: 0, dateAdded: 0, title: 'A', artist: '', album: ''), + songWith(id: 7, dateModified: 0, dateAdded: 0, title: 'a', artist: '', album: ''), + songWith(id: 6, dateModified: 0, dateAdded: 0, title: 'AA', artist: '', album: ''), + songWith(id: 8, dateModified: 0, dateAdded: 0, title: 'z', artist: '', album: ''), + songWith(id: 13, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'A'), + songWith(id: 15, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'a'), + songWith(id: 14, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'AA'), + songWith(id: 16, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'z'), + ], }, SortOrder.descending: { - SongSortFeature.dateModified: [1, 8, 6, 5, 7, 0, 3, 4, 9, 10, 11, 12, 13, 14, 15, 16, 2], - SongSortFeature.dateAdded: [3, 8, 6, 5, 7, 0, 1, 2, 9, 10, 11, 12, 13, 14, 15, 16, 4], - SongSortFeature.title: [8, 6, 5, 7, 1, 0, 3, 4, 9, 10, 11, 12, 13, 14, 15, 16, 2], - SongSortFeature.artist: [12, 10, 9, 11, 8, 6, 5, 7, 0, 1, 2, 3, 4, 13, 14, 15, 16], - SongSortFeature.album: [16, 14, 13, 15, 8, 6, 5, 7, 0, 1, 2, 3, 4, 9, 10, 11, 12], + SongSortFeature.dateModified: [ + songWith(id: 1, dateModified: 1, dateAdded: 0, title: '', artist: '', album: ''), + songWith(id: 8, dateModified: 0, dateAdded: 0, title: 'z', artist: '', album: ''), + songWith(id: 6, dateModified: 0, dateAdded: 0, title: 'AA', artist: '', album: ''), + songWith(id: 5, dateModified: 0, dateAdded: 0, title: 'A', artist: '', album: ''), + songWith(id: 7, dateModified: 0, dateAdded: 0, title: 'a', artist: '', album: ''), + songWith(id: 0, dateModified: 0, dateAdded: 0, title: '', artist: '', album: ''), + songWith(id: 3, dateModified: 0, dateAdded: 1, title: '', artist: '', album: ''), + songWith(id: 4, dateModified: 0, dateAdded: -1, title: '', artist: '', album: ''), + songWith(id: 9, dateModified: 0, dateAdded: 0, title: '', artist: 'A', album: ''), + songWith(id: 10, dateModified: 0, dateAdded: 0, title: '', artist: 'AA', album: ''), + songWith(id: 11, dateModified: 0, dateAdded: 0, title: '', artist: 'a', album: ''), + songWith(id: 12, dateModified: 0, dateAdded: 0, title: '', artist: 'z', album: ''), + songWith(id: 13, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'A'), + songWith(id: 14, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'AA'), + songWith(id: 15, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'a'), + songWith(id: 16, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'z'), + songWith(id: 2, dateModified: -1, dateAdded: 0, title: '', artist: '', album: ''), + ], + SongSortFeature.dateAdded: [ + songWith(id: 3, dateModified: 0, dateAdded: 1, title: '', artist: '', album: ''), + songWith(id: 8, dateModified: 0, dateAdded: 0, title: 'z', artist: '', album: ''), + songWith(id: 6, dateModified: 0, dateAdded: 0, title: 'AA', artist: '', album: ''), + songWith(id: 5, dateModified: 0, dateAdded: 0, title: 'A', artist: '', album: ''), + songWith(id: 7, dateModified: 0, dateAdded: 0, title: 'a', artist: '', album: ''), + songWith(id: 0, dateModified: 0, dateAdded: 0, title: '', artist: '', album: ''), + songWith(id: 1, dateModified: 1, dateAdded: 0, title: '', artist: '', album: ''), + songWith(id: 2, dateModified: -1, dateAdded: 0, title: '', artist: '', album: ''), + songWith(id: 9, dateModified: 0, dateAdded: 0, title: '', artist: 'A', album: ''), + songWith(id: 10, dateModified: 0, dateAdded: 0, title: '', artist: 'AA', album: ''), + songWith(id: 11, dateModified: 0, dateAdded: 0, title: '', artist: 'a', album: ''), + songWith(id: 12, dateModified: 0, dateAdded: 0, title: '', artist: 'z', album: ''), + songWith(id: 13, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'A'), + songWith(id: 14, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'AA'), + songWith(id: 15, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'a'), + songWith(id: 16, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'z'), + songWith(id: 4, dateModified: 0, dateAdded: -1, title: '', artist: '', album: ''), + ], + SongSortFeature.title: [ + songWith(id: 8, dateModified: 0, dateAdded: 0, title: 'z', artist: '', album: ''), + songWith(id: 6, dateModified: 0, dateAdded: 0, title: 'AA', artist: '', album: ''), + songWith(id: 5, dateModified: 0, dateAdded: 0, title: 'A', artist: '', album: ''), + songWith(id: 7, dateModified: 0, dateAdded: 0, title: 'a', artist: '', album: ''), + songWith(id: 1, dateModified: 1, dateAdded: 0, title: '', artist: '', album: ''), + songWith(id: 0, dateModified: 0, dateAdded: 0, title: '', artist: '', album: ''), + songWith(id: 3, dateModified: 0, dateAdded: 1, title: '', artist: '', album: ''), + songWith(id: 4, dateModified: 0, dateAdded: -1, title: '', artist: '', album: ''), + songWith(id: 9, dateModified: 0, dateAdded: 0, title: '', artist: 'A', album: ''), + songWith(id: 10, dateModified: 0, dateAdded: 0, title: '', artist: 'AA', album: ''), + songWith(id: 11, dateModified: 0, dateAdded: 0, title: '', artist: 'a', album: ''), + songWith(id: 12, dateModified: 0, dateAdded: 0, title: '', artist: 'z', album: ''), + songWith(id: 13, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'A'), + songWith(id: 14, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'AA'), + songWith(id: 15, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'a'), + songWith(id: 16, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'z'), + songWith(id: 2, dateModified: -1, dateAdded: 0, title: '', artist: '', album: ''), + ], + SongSortFeature.artist: [ + songWith(id: 12, dateModified: 0, dateAdded: 0, title: '', artist: 'z', album: ''), + songWith(id: 10, dateModified: 0, dateAdded: 0, title: '', artist: 'AA', album: ''), + songWith(id: 9, dateModified: 0, dateAdded: 0, title: '', artist: 'A', album: ''), + songWith(id: 11, dateModified: 0, dateAdded: 0, title: '', artist: 'a', album: ''), + songWith(id: 8, dateModified: 0, dateAdded: 0, title: 'z', artist: '', album: ''), + songWith(id: 6, dateModified: 0, dateAdded: 0, title: 'AA', artist: '', album: ''), + songWith(id: 5, dateModified: 0, dateAdded: 0, title: 'A', artist: '', album: ''), + songWith(id: 7, dateModified: 0, dateAdded: 0, title: 'a', artist: '', album: ''), + songWith(id: 0, dateModified: 0, dateAdded: 0, title: '', artist: '', album: ''), + songWith(id: 1, dateModified: 1, dateAdded: 0, title: '', artist: '', album: ''), + songWith(id: 2, dateModified: -1, dateAdded: 0, title: '', artist: '', album: ''), + songWith(id: 3, dateModified: 0, dateAdded: 1, title: '', artist: '', album: ''), + songWith(id: 4, dateModified: 0, dateAdded: -1, title: '', artist: '', album: ''), + songWith(id: 13, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'A'), + songWith(id: 14, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'AA'), + songWith(id: 15, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'a'), + songWith(id: 16, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'z'), + ], + SongSortFeature.album: [ + songWith(id: 16, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'z'), + songWith(id: 14, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'AA'), + songWith(id: 13, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'A'), + songWith(id: 15, dateModified: 0, dateAdded: 0, title: '', artist: '', album: 'a'), + songWith(id: 8, dateModified: 0, dateAdded: 0, title: 'z', artist: '', album: ''), + songWith(id: 6, dateModified: 0, dateAdded: 0, title: 'AA', artist: '', album: ''), + songWith(id: 5, dateModified: 0, dateAdded: 0, title: 'A', artist: '', album: ''), + songWith(id: 7, dateModified: 0, dateAdded: 0, title: 'a', artist: '', album: ''), + songWith(id: 0, dateModified: 0, dateAdded: 0, title: '', artist: '', album: ''), + songWith(id: 1, dateModified: 1, dateAdded: 0, title: '', artist: '', album: ''), + songWith(id: 2, dateModified: -1, dateAdded: 0, title: '', artist: '', album: ''), + songWith(id: 3, dateModified: 0, dateAdded: 1, title: '', artist: '', album: ''), + songWith(id: 4, dateModified: 0, dateAdded: -1, title: '', artist: '', album: ''), + songWith(id: 9, dateModified: 0, dateAdded: 0, title: '', artist: 'A', album: ''), + songWith(id: 10, dateModified: 0, dateAdded: 0, title: '', artist: 'AA', album: ''), + songWith(id: 11, dateModified: 0, dateAdded: 0, title: '', artist: 'a', album: ''), + songWith(id: 12, dateModified: 0, dateAdded: 0, title: '', artist: 'z', album: ''), + ], }, }; for (final MapEntry(key: sortOrder, value: featureTestCases) in testCases.entries) { for (final MapEntry(key: feature, value: expectedContentList) in featureTestCases.entries) { test('Sorts songs by ${feature.name} ${sortOrder.name}', () async { expect( - songs.toList()..sort(SongSort(feature: feature, order: sortOrder).comparator), - expectedContentList.map((i) => songs[i]).toList(), + (songs.toList()..sort(SongSort(feature: feature, order: sortOrder).comparator)) + .map((song) => song.toMap()) + .toList(), + expectedContentList.map((song) => song.toMap()).toList(), ); }); } @@ -75,26 +257,172 @@ void main() { albumWith(id: 16, album: '', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: -1), ]; }); - final Map>> testCases = { + final Map>> testCases = { SortOrder.ascending: { - AlbumSortFeature.title: [10, 13, 0, 5, 6, 7, 8, 11, 14, 15, 16, 9, 12, 1, 3, 2, 4], - AlbumSortFeature.artist: [10, 13, 0, 1, 2, 3, 4, 11, 14, 15, 16, 9, 12, 5, 7, 6, 8], - AlbumSortFeature.year: [10, 13, 0, 5, 6, 7, 8, 11, 14, 15, 16, 1, 3, 2, 4, 9, 12], - AlbumSortFeature.numberOfSongs: [16, 10, 13, 0, 1, 2, 3, 4, 5, 6, 7, 8, 11, 14, 9, 12, 15], + AlbumSortFeature.title: [ + albumWith(id: 10, album: '', artist: '', lastYear: -1, firstYear: 0, numberOfSongs: 0), + albumWith(id: 13, album: '', artist: '', lastYear: null, firstYear: -1, numberOfSongs: 0), + albumWith(id: 0, album: '', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 5, album: '', artist: 'A', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 6, album: '', artist: 'AA', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 7, album: '', artist: 'a', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 8, album: '', artist: 'z', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 11, album: '', artist: '', lastYear: null, firstYear: 0, numberOfSongs: 0), + albumWith(id: 14, album: '', artist: '', lastYear: null, firstYear: null, numberOfSongs: 0), + albumWith(id: 15, album: '', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 1), + albumWith(id: 16, album: '', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: -1), + albumWith(id: 9, album: '', artist: '', lastYear: 1, firstYear: 0, numberOfSongs: 0), + albumWith(id: 12, album: '', artist: '', lastYear: null, firstYear: 1, numberOfSongs: 0), + albumWith(id: 1, album: 'A', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 3, album: 'a', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 2, album: 'AA', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 4, album: 'z', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + ], + AlbumSortFeature.artist: [ + albumWith(id: 10, album: '', artist: '', lastYear: -1, firstYear: 0, numberOfSongs: 0), + albumWith(id: 13, album: '', artist: '', lastYear: null, firstYear: -1, numberOfSongs: 0), + albumWith(id: 0, album: '', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 1, album: 'A', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 2, album: 'AA', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 3, album: 'a', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 4, album: 'z', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 11, album: '', artist: '', lastYear: null, firstYear: 0, numberOfSongs: 0), + albumWith(id: 14, album: '', artist: '', lastYear: null, firstYear: null, numberOfSongs: 0), + albumWith(id: 15, album: '', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 1), + albumWith(id: 16, album: '', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: -1), + albumWith(id: 9, album: '', artist: '', lastYear: 1, firstYear: 0, numberOfSongs: 0), + albumWith(id: 12, album: '', artist: '', lastYear: null, firstYear: 1, numberOfSongs: 0), + albumWith(id: 5, album: '', artist: 'A', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 7, album: '', artist: 'a', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 6, album: '', artist: 'AA', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 8, album: '', artist: 'z', lastYear: 0, firstYear: 0, numberOfSongs: 0), + ], + AlbumSortFeature.year: [ + albumWith(id: 10, album: '', artist: '', lastYear: -1, firstYear: 0, numberOfSongs: 0), + albumWith(id: 13, album: '', artist: '', lastYear: null, firstYear: -1, numberOfSongs: 0), + albumWith(id: 0, album: '', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 5, album: '', artist: 'A', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 6, album: '', artist: 'AA', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 7, album: '', artist: 'a', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 8, album: '', artist: 'z', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 11, album: '', artist: '', lastYear: null, firstYear: 0, numberOfSongs: 0), + albumWith(id: 14, album: '', artist: '', lastYear: null, firstYear: null, numberOfSongs: 0), + albumWith(id: 15, album: '', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 1), + albumWith(id: 16, album: '', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: -1), + albumWith(id: 1, album: 'A', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 3, album: 'a', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 2, album: 'AA', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 4, album: 'z', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 9, album: '', artist: '', lastYear: 1, firstYear: 0, numberOfSongs: 0), + albumWith(id: 12, album: '', artist: '', lastYear: null, firstYear: 1, numberOfSongs: 0), + ], + AlbumSortFeature.numberOfSongs: [ + albumWith(id: 16, album: '', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: -1), + albumWith(id: 10, album: '', artist: '', lastYear: -1, firstYear: 0, numberOfSongs: 0), + albumWith(id: 13, album: '', artist: '', lastYear: null, firstYear: -1, numberOfSongs: 0), + albumWith(id: 0, album: '', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 1, album: 'A', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 2, album: 'AA', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 3, album: 'a', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 4, album: 'z', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 5, album: '', artist: 'A', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 6, album: '', artist: 'AA', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 7, album: '', artist: 'a', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 8, album: '', artist: 'z', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 11, album: '', artist: '', lastYear: null, firstYear: 0, numberOfSongs: 0), + albumWith(id: 14, album: '', artist: '', lastYear: null, firstYear: null, numberOfSongs: 0), + albumWith(id: 9, album: '', artist: '', lastYear: 1, firstYear: 0, numberOfSongs: 0), + albumWith(id: 12, album: '', artist: '', lastYear: null, firstYear: 1, numberOfSongs: 0), + albumWith(id: 15, album: '', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 1), + ], }, SortOrder.descending: { - AlbumSortFeature.title: [4, 2, 1, 3, 9, 12, 0, 5, 6, 7, 8, 11, 14, 15, 16, 10, 13], - AlbumSortFeature.artist: [8, 6, 5, 7, 9, 12, 0, 1, 2, 3, 4, 11, 14, 15, 16, 10, 13], - AlbumSortFeature.year: [9, 12, 4, 2, 1, 3, 0, 5, 6, 7, 8, 11, 14, 15, 16, 10, 13], - AlbumSortFeature.numberOfSongs: [15, 9, 12, 0, 1, 2, 3, 4, 5, 6, 7, 8, 11, 14, 10, 13, 16], + AlbumSortFeature.title: [ + albumWith(id: 4, album: 'z', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 2, album: 'AA', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 1, album: 'A', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 3, album: 'a', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 9, album: '', artist: '', lastYear: 1, firstYear: 0, numberOfSongs: 0), + albumWith(id: 12, album: '', artist: '', lastYear: null, firstYear: 1, numberOfSongs: 0), + albumWith(id: 0, album: '', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 5, album: '', artist: 'A', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 6, album: '', artist: 'AA', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 7, album: '', artist: 'a', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 8, album: '', artist: 'z', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 11, album: '', artist: '', lastYear: null, firstYear: 0, numberOfSongs: 0), + albumWith(id: 14, album: '', artist: '', lastYear: null, firstYear: null, numberOfSongs: 0), + albumWith(id: 15, album: '', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 1), + albumWith(id: 16, album: '', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: -1), + albumWith(id: 10, album: '', artist: '', lastYear: -1, firstYear: 0, numberOfSongs: 0), + albumWith(id: 13, album: '', artist: '', lastYear: null, firstYear: -1, numberOfSongs: 0), + ], + AlbumSortFeature.artist: [ + albumWith(id: 8, album: '', artist: 'z', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 6, album: '', artist: 'AA', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 5, album: '', artist: 'A', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 7, album: '', artist: 'a', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 9, album: '', artist: '', lastYear: 1, firstYear: 0, numberOfSongs: 0), + albumWith(id: 12, album: '', artist: '', lastYear: null, firstYear: 1, numberOfSongs: 0), + albumWith(id: 0, album: '', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 1, album: 'A', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 2, album: 'AA', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 3, album: 'a', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 4, album: 'z', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 11, album: '', artist: '', lastYear: null, firstYear: 0, numberOfSongs: 0), + albumWith(id: 14, album: '', artist: '', lastYear: null, firstYear: null, numberOfSongs: 0), + albumWith(id: 15, album: '', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 1), + albumWith(id: 16, album: '', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: -1), + albumWith(id: 10, album: '', artist: '', lastYear: -1, firstYear: 0, numberOfSongs: 0), + albumWith(id: 13, album: '', artist: '', lastYear: null, firstYear: -1, numberOfSongs: 0), + ], + AlbumSortFeature.year: [ + albumWith(id: 9, album: '', artist: '', lastYear: 1, firstYear: 0, numberOfSongs: 0), + albumWith(id: 12, album: '', artist: '', lastYear: null, firstYear: 1, numberOfSongs: 0), + albumWith(id: 4, album: 'z', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 2, album: 'AA', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 1, album: 'A', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 3, album: 'a', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 0, album: '', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 5, album: '', artist: 'A', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 6, album: '', artist: 'AA', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 7, album: '', artist: 'a', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 8, album: '', artist: 'z', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 11, album: '', artist: '', lastYear: null, firstYear: 0, numberOfSongs: 0), + albumWith(id: 14, album: '', artist: '', lastYear: null, firstYear: null, numberOfSongs: 0), + albumWith(id: 15, album: '', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 1), + albumWith(id: 16, album: '', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: -1), + albumWith(id: 10, album: '', artist: '', lastYear: -1, firstYear: 0, numberOfSongs: 0), + albumWith(id: 13, album: '', artist: '', lastYear: null, firstYear: -1, numberOfSongs: 0), + ], + AlbumSortFeature.numberOfSongs: [ + albumWith(id: 15, album: '', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 1), + albumWith(id: 9, album: '', artist: '', lastYear: 1, firstYear: 0, numberOfSongs: 0), + albumWith(id: 12, album: '', artist: '', lastYear: null, firstYear: 1, numberOfSongs: 0), + albumWith(id: 0, album: '', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 1, album: 'A', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 2, album: 'AA', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 3, album: 'a', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 4, album: 'z', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 5, album: '', artist: 'A', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 6, album: '', artist: 'AA', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 7, album: '', artist: 'a', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 8, album: '', artist: 'z', lastYear: 0, firstYear: 0, numberOfSongs: 0), + albumWith(id: 11, album: '', artist: '', lastYear: null, firstYear: 0, numberOfSongs: 0), + albumWith(id: 14, album: '', artist: '', lastYear: null, firstYear: null, numberOfSongs: 0), + albumWith(id: 10, album: '', artist: '', lastYear: -1, firstYear: 0, numberOfSongs: 0), + albumWith(id: 13, album: '', artist: '', lastYear: null, firstYear: -1, numberOfSongs: 0), + albumWith(id: 16, album: '', artist: '', lastYear: 0, firstYear: 0, numberOfSongs: -1), + ], }, }; for (final MapEntry(key: sortOrder, value: featureTestCases) in testCases.entries) { for (final MapEntry(key: feature, value: expectedContentList) in featureTestCases.entries) { test('Sorts albums by ${feature.name} ${sortOrder.name}', () async { expect( - albums.toList()..sort(AlbumSort(feature: feature, order: sortOrder).comparator), - expectedContentList.map((i) => albums[i]).toList(), + (albums.toList()..sort(AlbumSort(feature: feature, order: sortOrder).comparator)) + .map((album) => album.toMap()) + .toList(), + expectedContentList.map((album) => album.toMap()).toList(), ); }); } @@ -116,24 +444,86 @@ void main() { playlistWith(id: 8, name: '', dateModified: 0, dateAdded: -1), ]; }); - final Map>> testCases = { + final Map>> testCases = { SortOrder.ascending: { - PlaylistSortFeature.dateModified: [6, 0, 7, 8, 1, 3, 2, 4, 5], - PlaylistSortFeature.dateAdded: [8, 0, 5, 6, 1, 3, 2, 4, 7], - PlaylistSortFeature.name: [6, 0, 7, 8, 5, 1, 3, 2, 4], + PlaylistSortFeature.dateModified: [ + playlistWith(id: 6, name: '', dateModified: -1, dateAdded: 0), + playlistWith(id: 0, name: '', dateModified: 0, dateAdded: 0), + playlistWith(id: 7, name: '', dateModified: 0, dateAdded: 1), + playlistWith(id: 8, name: '', dateModified: 0, dateAdded: -1), + playlistWith(id: 1, name: 'A', dateModified: 0, dateAdded: 0), + playlistWith(id: 3, name: 'a', dateModified: 0, dateAdded: 0), + playlistWith(id: 2, name: 'AA', dateModified: 0, dateAdded: 0), + playlistWith(id: 4, name: 'z', dateModified: 0, dateAdded: 0), + playlistWith(id: 5, name: '', dateModified: 1, dateAdded: 0), + ], + PlaylistSortFeature.dateAdded: [ + playlistWith(id: 8, name: '', dateModified: 0, dateAdded: -1), + playlistWith(id: 0, name: '', dateModified: 0, dateAdded: 0), + playlistWith(id: 5, name: '', dateModified: 1, dateAdded: 0), + playlistWith(id: 6, name: '', dateModified: -1, dateAdded: 0), + playlistWith(id: 1, name: 'A', dateModified: 0, dateAdded: 0), + playlistWith(id: 3, name: 'a', dateModified: 0, dateAdded: 0), + playlistWith(id: 2, name: 'AA', dateModified: 0, dateAdded: 0), + playlistWith(id: 4, name: 'z', dateModified: 0, dateAdded: 0), + playlistWith(id: 7, name: '', dateModified: 0, dateAdded: 1), + ], + PlaylistSortFeature.name: [ + playlistWith(id: 6, name: '', dateModified: -1, dateAdded: 0), + playlistWith(id: 0, name: '', dateModified: 0, dateAdded: 0), + playlistWith(id: 7, name: '', dateModified: 0, dateAdded: 1), + playlistWith(id: 8, name: '', dateModified: 0, dateAdded: -1), + playlistWith(id: 5, name: '', dateModified: 1, dateAdded: 0), + playlistWith(id: 1, name: 'A', dateModified: 0, dateAdded: 0), + playlistWith(id: 3, name: 'a', dateModified: 0, dateAdded: 0), + playlistWith(id: 2, name: 'AA', dateModified: 0, dateAdded: 0), + playlistWith(id: 4, name: 'z', dateModified: 0, dateAdded: 0), + ], }, SortOrder.descending: { - PlaylistSortFeature.dateModified: [5, 4, 2, 1, 3, 0, 7, 8, 6], - PlaylistSortFeature.dateAdded: [7, 4, 2, 1, 3, 0, 5, 6, 8], - PlaylistSortFeature.name: [4, 2, 1, 3, 5, 0, 7, 8, 6], + PlaylistSortFeature.dateModified: [ + playlistWith(id: 5, name: '', dateModified: 1, dateAdded: 0), + playlistWith(id: 4, name: 'z', dateModified: 0, dateAdded: 0), + playlistWith(id: 2, name: 'AA', dateModified: 0, dateAdded: 0), + playlistWith(id: 1, name: 'A', dateModified: 0, dateAdded: 0), + playlistWith(id: 3, name: 'a', dateModified: 0, dateAdded: 0), + playlistWith(id: 0, name: '', dateModified: 0, dateAdded: 0), + playlistWith(id: 7, name: '', dateModified: 0, dateAdded: 1), + playlistWith(id: 8, name: '', dateModified: 0, dateAdded: -1), + playlistWith(id: 6, name: '', dateModified: -1, dateAdded: 0), + ], + PlaylistSortFeature.dateAdded: [ + playlistWith(id: 7, name: '', dateModified: 0, dateAdded: 1), + playlistWith(id: 4, name: 'z', dateModified: 0, dateAdded: 0), + playlistWith(id: 2, name: 'AA', dateModified: 0, dateAdded: 0), + playlistWith(id: 1, name: 'A', dateModified: 0, dateAdded: 0), + playlistWith(id: 3, name: 'a', dateModified: 0, dateAdded: 0), + playlistWith(id: 0, name: '', dateModified: 0, dateAdded: 0), + playlistWith(id: 5, name: '', dateModified: 1, dateAdded: 0), + playlistWith(id: 6, name: '', dateModified: -1, dateAdded: 0), + playlistWith(id: 8, name: '', dateModified: 0, dateAdded: -1), + ], + PlaylistSortFeature.name: [ + playlistWith(id: 4, name: 'z', dateModified: 0, dateAdded: 0), + playlistWith(id: 2, name: 'AA', dateModified: 0, dateAdded: 0), + playlistWith(id: 1, name: 'A', dateModified: 0, dateAdded: 0), + playlistWith(id: 3, name: 'a', dateModified: 0, dateAdded: 0), + playlistWith(id: 5, name: '', dateModified: 1, dateAdded: 0), + playlistWith(id: 0, name: '', dateModified: 0, dateAdded: 0), + playlistWith(id: 7, name: '', dateModified: 0, dateAdded: 1), + playlistWith(id: 8, name: '', dateModified: 0, dateAdded: -1), + playlistWith(id: 6, name: '', dateModified: -1, dateAdded: 0), + ], }, }; for (final MapEntry(key: sortOrder, value: featureTestCases) in testCases.entries) { for (final MapEntry(key: feature, value: expectedContentList) in featureTestCases.entries) { test('Sorts playlists by ${feature.name} ${sortOrder.name}', () async { expect( - playlists.toList()..sort(PlaylistSort(feature: feature, order: sortOrder).comparator), - expectedContentList.map((i) => playlists[i]).toList(), + (playlists.toList()..sort(PlaylistSort(feature: feature, order: sortOrder).comparator)) + .map((playlist) => playlist.toMap()) + .toList(), + expectedContentList.map((playlist) => playlist.toMap()).toList(), ); }); } @@ -155,24 +545,86 @@ void main() { artistWith(id: 8, artist: '', numberOfAlbums: 0, numberOfTracks: -1), ]; }); - final Map>> testCases = { + final Map>> testCases = { SortOrder.ascending: { - ArtistSortFeature.name: [8, 0, 5, 6, 7, 1, 3, 2, 4], - ArtistSortFeature.numberOfAlbums: [6, 0, 7, 8, 1, 3, 2, 4, 5], - ArtistSortFeature.numberOfTracks: [8, 0, 5, 6, 1, 3, 2, 4, 7], + ArtistSortFeature.name: [ + artistWith(id: 8, artist: '', numberOfAlbums: 0, numberOfTracks: -1), + artistWith(id: 0, artist: '', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 5, artist: '', numberOfAlbums: 1, numberOfTracks: 0), + artistWith(id: 6, artist: '', numberOfAlbums: -1, numberOfTracks: 0), + artistWith(id: 7, artist: '', numberOfAlbums: 0, numberOfTracks: 1), + artistWith(id: 1, artist: 'A', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 3, artist: 'a', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 2, artist: 'AA', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 4, artist: 'z', numberOfAlbums: 0, numberOfTracks: 0), + ], + ArtistSortFeature.numberOfAlbums: [ + artistWith(id: 6, artist: '', numberOfAlbums: -1, numberOfTracks: 0), + artistWith(id: 0, artist: '', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 7, artist: '', numberOfAlbums: 0, numberOfTracks: 1), + artistWith(id: 8, artist: '', numberOfAlbums: 0, numberOfTracks: -1), + artistWith(id: 1, artist: 'A', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 3, artist: 'a', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 2, artist: 'AA', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 4, artist: 'z', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 5, artist: '', numberOfAlbums: 1, numberOfTracks: 0), + ], + ArtistSortFeature.numberOfTracks: [ + artistWith(id: 8, artist: '', numberOfAlbums: 0, numberOfTracks: -1), + artistWith(id: 0, artist: '', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 5, artist: '', numberOfAlbums: 1, numberOfTracks: 0), + artistWith(id: 6, artist: '', numberOfAlbums: -1, numberOfTracks: 0), + artistWith(id: 1, artist: 'A', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 3, artist: 'a', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 2, artist: 'AA', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 4, artist: 'z', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 7, artist: '', numberOfAlbums: 0, numberOfTracks: 1), + ], }, SortOrder.descending: { - ArtistSortFeature.name: [4, 2, 1, 3, 7, 0, 5, 6, 8], - ArtistSortFeature.numberOfAlbums: [5, 4, 2, 1, 3, 0, 7, 8, 6], - ArtistSortFeature.numberOfTracks: [7, 4, 2, 1, 3, 0, 5, 6, 8], + ArtistSortFeature.name: [ + artistWith(id: 4, artist: 'z', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 2, artist: 'AA', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 1, artist: 'A', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 3, artist: 'a', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 7, artist: '', numberOfAlbums: 0, numberOfTracks: 1), + artistWith(id: 0, artist: '', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 5, artist: '', numberOfAlbums: 1, numberOfTracks: 0), + artistWith(id: 6, artist: '', numberOfAlbums: -1, numberOfTracks: 0), + artistWith(id: 8, artist: '', numberOfAlbums: 0, numberOfTracks: -1), + ], + ArtistSortFeature.numberOfAlbums: [ + artistWith(id: 5, artist: '', numberOfAlbums: 1, numberOfTracks: 0), + artistWith(id: 4, artist: 'z', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 2, artist: 'AA', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 1, artist: 'A', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 3, artist: 'a', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 0, artist: '', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 7, artist: '', numberOfAlbums: 0, numberOfTracks: 1), + artistWith(id: 8, artist: '', numberOfAlbums: 0, numberOfTracks: -1), + artistWith(id: 6, artist: '', numberOfAlbums: -1, numberOfTracks: 0), + ], + ArtistSortFeature.numberOfTracks: [ + artistWith(id: 7, artist: '', numberOfAlbums: 0, numberOfTracks: 1), + artistWith(id: 4, artist: 'z', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 2, artist: 'AA', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 1, artist: 'A', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 3, artist: 'a', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 0, artist: '', numberOfAlbums: 0, numberOfTracks: 0), + artistWith(id: 5, artist: '', numberOfAlbums: 1, numberOfTracks: 0), + artistWith(id: 6, artist: '', numberOfAlbums: -1, numberOfTracks: 0), + artistWith(id: 8, artist: '', numberOfAlbums: 0, numberOfTracks: -1), + ], }, }; for (final MapEntry(key: sortOrder, value: featureTestCases) in testCases.entries) { for (final MapEntry(key: feature, value: expectedContentList) in featureTestCases.entries) { test('Sorts artists by ${feature.name} ${sortOrder.name}', () async { expect( - artists.toList()..sort(ArtistSort(feature: feature, order: sortOrder).comparator), - expectedContentList.map((i) => artists[i]).toList(), + (artists.toList()..sort(ArtistSort(feature: feature, order: sortOrder).comparator)) + .map((artist) => artist.toMap()) + .toList(), + expectedContentList.map((artist) => artist.toMap()).toList(), ); }); } From 0a64cffe2862c8d84e16fbb35267c32a12f3763f Mon Sep 17 00:00:00 2001 From: Abestanis Date: Mon, 14 Oct 2024 12:46:53 +0200 Subject: [PATCH 6/6] Fix Sort.toMap --- lib/logic/models/sort.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/logic/models/sort.dart b/lib/logic/models/sort.dart index ca3f75209..f5e827a49 100644 --- a/lib/logic/models/sort.dart +++ b/lib/logic/models/sort.dart @@ -160,7 +160,7 @@ abstract class Sort extends Equatable { Map toMap() => { 'feature': feature.id, - 'order': order, + 'order': order.name, }; }