From 1117da068b9adf6d63d99903ad10bd19549774c2 Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Wed, 16 Aug 2023 22:29:52 +0200 Subject: [PATCH] test fix, tuple record migration wip --- lib/model/covers.dart | 9 ++-- lib/model/filters/album.dart | 2 +- lib/model/filters/filters.dart | 2 +- lib/model/source/collection_source.dart | 8 ++-- lib/model/source/location/location.dart | 7 ++- lib/services/common/service_policy.dart | 13 +++--- lib/utils/math_utils.dart | 20 ++++----- .../common/tile_extent_controller.dart | 3 +- lib/widgets/dialogs/add_shortcut_dialog.dart | 2 +- lib/widgets/dialogs/tile_view_dialog.dart | 4 +- .../common/action_delegates/chip_set.dart | 6 +-- test/model/collection_source_test.dart | 43 +++++++++++-------- test/utils/math_utils_test.dart | 5 +-- 13 files changed, 61 insertions(+), 63 deletions(-) diff --git a/lib/model/covers.dart b/lib/model/covers.dart index b36dee1a9..340b8f8cc 100644 --- a/lib/model/covers.dart +++ b/lib/model/covers.dart @@ -13,7 +13,6 @@ import 'package:collection/collection.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/painting.dart'; -import 'package:tuple/tuple.dart'; final Covers covers = Covers._private(); @@ -40,11 +39,11 @@ class Covers { Set get all => Set.unmodifiable(_rows); - Tuple3? of(CollectionFilter filter) { + (int? entryId, String? packageName, Color? color)? of(CollectionFilter filter) { if (filter is AlbumFilter && vaults.isLocked(filter.album)) return null; final row = _rows.firstWhereOrNull((row) => row.filter == filter); - return row != null ? Tuple3(row.entryId, row.packageName, row.color) : null; + return row != null ? (row.entryId, row.packageName, row.color) : null; } Future set({ @@ -113,7 +112,7 @@ class Covers { } AlbumType effectiveAlbumType(String albumPath) { - final filterPackage = of(AlbumFilter(albumPath, null))?.item2; + final filterPackage = of(AlbumFilter(albumPath, null))?.$2; if (filterPackage != null) { return filterPackage.isEmpty ? AlbumType.regular : AlbumType.app; } else { @@ -122,7 +121,7 @@ class Covers { } String? effectiveAlbumPackage(String albumPath) { - final filterPackage = of(AlbumFilter(albumPath, null))?.item2; + final filterPackage = of(AlbumFilter(albumPath, null))?.$2; return filterPackage ?? appInventory.getAlbumAppPackageName(albumPath); } diff --git a/lib/model/filters/album.dart b/lib/model/filters/album.dart index 34e4ab626..d2126c938 100644 --- a/lib/model/filters/album.dart +++ b/lib/model/filters/album.dart @@ -64,7 +64,7 @@ class AlbumFilter extends CoveredCollectionFilter { @override Future color(BuildContext context) { // custom color has precedence over others, even custom app color - final customColor = covers.of(this)?.item3; + final customColor = covers.of(this)?.$3; if (customColor != null) return SynchronousFuture(customColor); final colors = context.read(); diff --git a/lib/model/filters/filters.dart b/lib/model/filters/filters.dart index 212b6c92d..b6e08e2b9 100644 --- a/lib/model/filters/filters.dart +++ b/lib/model/filters/filters.dart @@ -157,7 +157,7 @@ abstract class CoveredCollectionFilter extends CollectionFilter { @override Future color(BuildContext context) { - final customColor = covers.of(this)?.item3; + final customColor = covers.of(this)?.$3; if (customColor != null) { return SynchronousFuture(customColor); } diff --git a/lib/model/source/collection_source.dart b/lib/model/source/collection_source.dart index a6b76d4c4..385131a9f 100644 --- a/lib/model/source/collection_source.dart +++ b/lib/model/source/collection_source.dart @@ -274,9 +274,9 @@ abstract class CollectionSource with SourceBase, AlbumMixin, CountryMixin, Place final existingCover = covers.of(oldFilter); await covers.set( filter: newFilter, - entryId: existingCover?.item1, - packageName: existingCover?.item2, - color: existingCover?.item3, + entryId: existingCover?.$1, + packageName: existingCover?.$2, + color: existingCover?.$3, ); renameNewAlbum(sourceAlbum, destinationAlbum); @@ -547,7 +547,7 @@ abstract class CollectionSource with SourceBase, AlbumMixin, CountryMixin, Place } AvesEntry? coverEntry(CollectionFilter filter) { - final id = covers.of(filter)?.item1; + final id = covers.of(filter)?.$1; if (id != null) { final entry = visibleEntries.firstWhereOrNull((entry) => entry.id == id); if (entry != null) return entry; diff --git a/lib/model/source/location/location.dart b/lib/model/source/location/location.dart index d0dadab88..09f89d38d 100644 --- a/lib/model/source/location/location.dart +++ b/lib/model/source/location/location.dart @@ -14,7 +14,6 @@ import 'package:aves/services/common/services.dart'; import 'package:aves_model/aves_model.dart'; import 'package:collection/collection.dart'; import 'package:flutter/foundation.dart'; -import 'package:tuple/tuple.dart'; mixin LocationMixin on CountryMixin, StateMixin { static const commitCountThreshold = 200; @@ -96,16 +95,16 @@ mixin LocationMixin on CountryMixin, StateMixin { // - 652 calls (22%) when approximating to 2 decimal places (~1km - town or village) // cf https://en.wikipedia.org/wiki/Decimal_degrees#Precision final latLngFactor = pow(10, 2); - Tuple2 approximateLatLng(AvesEntry entry) { + (int latitude, int longitude) approximateLatLng(AvesEntry entry) { // entry has coordinates final catalogMetadata = entry.catalogMetadata!; final lat = catalogMetadata.latitude!; final lng = catalogMetadata.longitude!; - return Tuple2((lat * latLngFactor).round(), (lng * latLngFactor).round()); + return ((lat * latLngFactor).round(), (lng * latLngFactor).round()); } final located = visibleEntries.where((entry) => entry.hasGps).toSet().difference(todo); - final knownLocations = , AddressDetails?>{}; + final knownLocations = <(int, int), AddressDetails?>{}; located.forEach((entry) { knownLocations.putIfAbsent(approximateLatLng(entry), () => entry.addressDetails); }); diff --git a/lib/services/common/service_policy.dart b/lib/services/common/service_policy.dart index c2b7f5627..e2535533d 100644 --- a/lib/services/common/service_policy.dart +++ b/lib/services/common/service_policy.dart @@ -3,13 +3,12 @@ import 'dart:collection'; import 'package:collection/collection.dart'; import 'package:flutter/foundation.dart'; -import 'package:tuple/tuple.dart'; final ServicePolicy servicePolicy = ServicePolicy._private(); class ServicePolicy { final StreamController _queueStreamController = StreamController.broadcast(); - final Map> _paused = {}; + final Map _paused = {}; final SplayTreeMap> _queues = SplayTreeMap(); final LinkedHashMap _runningQueue = LinkedHashMap(); @@ -30,8 +29,8 @@ class ServicePolicy { key ??= platformCall.hashCode; final toResume = _paused.remove(key); if (toResume != null) { - priority = toResume.item1; - task = toResume.item2 as _Task; + priority = toResume.$1; + task = toResume.$2 as _Task; completer = task.completer; } else { completer = Completer(); @@ -56,8 +55,8 @@ class ServicePolicy { Future? resume(Object key) { final toResume = _paused.remove(key); if (toResume != null) { - final priority = toResume.item1; - final task = toResume.item2 as _Task; + final priority = toResume.$1; + final task = toResume.$2 as _Task; _getQueue(priority)[key] = task; _pickNext(); return task.completer.future; @@ -97,7 +96,7 @@ class ServicePolicy { } bool pause(Object key, Iterable priorities) { - return _takeOut(key, priorities, (priority, task) => _paused.putIfAbsent(key, () => Tuple2(priority, task))); + return _takeOut(key, priorities, (priority, task) => _paused.putIfAbsent(key, () => (priority, task))); } bool isPaused(Object key) => _paused.containsKey(key); diff --git a/lib/utils/math_utils.dart b/lib/utils/math_utils.dart index e882db4aa..82be6858d 100644 --- a/lib/utils/math_utils.dart +++ b/lib/utils/math_utils.dart @@ -1,8 +1,6 @@ import 'dart:math'; import 'dart:ui'; -import 'package:tuple/tuple.dart'; - int highestPowerOf2(num x) => x < 1 ? 0 : pow(2, (log(x) / ln2).floor()).toInt(); int smallestPowerOf2(num x) => x < 1 ? 1 : pow(2, (log(x) / ln2).ceil()).toInt(); @@ -10,16 +8,16 @@ int smallestPowerOf2(num x) => x < 1 ? 1 : pow(2, (log(x) / ln2).ceil()).toInt() double roundToPrecision(final double value, {required final int decimals}) => (value * pow(10, decimals)).round() / pow(10, decimals); // cf https://en.wikipedia.org/wiki/Intersection_(geometry)#Two_line_segments -Offset? segmentIntersection(Tuple2 s1, Tuple2 s2) { - final x1 = s1.item1.dx; - final y1 = s1.item1.dy; - final x2 = s1.item2.dx; - final y2 = s1.item2.dy; +Offset? segmentIntersection((Offset, Offset) s1, (Offset, Offset) s2) { + final x1 = s1.$1.dx; + final y1 = s1.$1.dy; + final x2 = s1.$2.dx; + final y2 = s1.$2.dy; - final x3 = s2.item1.dx; - final y3 = s2.item1.dy; - final x4 = s2.item2.dx; - final y4 = s2.item2.dy; + final x3 = s2.$1.dx; + final y3 = s2.$1.dy; + final x4 = s2.$2.dx; + final y4 = s2.$2.dy; final a1 = x2 - x1; final b1 = -(x4 - x3); diff --git a/lib/widgets/common/tile_extent_controller.dart b/lib/widgets/common/tile_extent_controller.dart index 10ae6dc9d..baaaefc84 100644 --- a/lib/widgets/common/tile_extent_controller.dart +++ b/lib/widgets/common/tile_extent_controller.dart @@ -4,7 +4,6 @@ import 'dart:math'; import 'package:aves/model/settings/settings.dart'; import 'package:flutter/scheduler.dart'; import 'package:flutter/widgets.dart'; -import 'package:tuple/tuple.dart'; class TileExtentController { final String settingsRouteKey; @@ -102,7 +101,7 @@ class TileExtentController { double get effectiveExtentMax => _extentForColumnCount(_effectiveColumnCountMin()); - Tuple2 get effectiveColumnRange => Tuple2(_effectiveColumnCountMin(), _effectiveColumnCountMax()); + (int min, int max) get effectiveColumnRange => (_effectiveColumnCountMin(), _effectiveColumnCountMax()); int get columnCount => _effectiveColumnCountForExtent(extentNotifier.value); diff --git a/lib/widgets/dialogs/add_shortcut_dialog.dart b/lib/widgets/dialogs/add_shortcut_dialog.dart index 095a836b8..b0e30f667 100644 --- a/lib/widgets/dialogs/add_shortcut_dialog.dart +++ b/lib/widgets/dialogs/add_shortcut_dialog.dart @@ -40,7 +40,7 @@ class _AddShortcutDialogState extends State { if (_collection != null) { final entries = _collection.sortedEntries; if (entries.isNotEmpty) { - final coverEntries = _collection.filters.map((filter) => covers.of(filter)?.item1).whereNotNull().map((id) => entries.firstWhereOrNull((entry) => entry.id == id)).whereNotNull(); + final coverEntries = _collection.filters.map((filter) => covers.of(filter)?.$1).whereNotNull().map((id) => entries.firstWhereOrNull((entry) => entry.id == id)).whereNotNull(); _coverEntry = coverEntries.firstOrNull ?? entries.first; } } diff --git a/lib/widgets/dialogs/tile_view_dialog.dart b/lib/widgets/dialogs/tile_view_dialog.dart index 941963e98..db8501c5c 100644 --- a/lib/widgets/dialogs/tile_view_dialog.dart +++ b/lib/widgets/dialogs/tile_view_dialog.dart @@ -70,8 +70,8 @@ class _TileViewDialogState extends State> with final extentController = tileExtentController; final columnRange = extentController.effectiveColumnRange; - _columnMin = columnRange.item1; - _columnMax = columnRange.item2; + _columnMin = columnRange.$1; + _columnMax = columnRange.$2; } @override diff --git a/lib/widgets/filter_grids/common/action_delegates/chip_set.dart b/lib/widgets/filter_grids/common/action_delegates/chip_set.dart index 16243ebc7..5fed06d3a 100644 --- a/lib/widgets/filter_grids/common/action_delegates/chip_set.dart +++ b/lib/widgets/filter_grids/common/action_delegates/chip_set.dart @@ -326,15 +326,15 @@ abstract class ChipSetActionDelegate with FeedbackMi if (!await unlockFilter(context, filter)) return; final existingCover = covers.of(filter); - final entryId = existingCover?.item1; + final entryId = existingCover?.$1; final customEntry = entryId != null ? context.read().visibleEntries.firstWhereOrNull((entry) => entry.id == entryId) : null; final selectedCover = await showDialog>( context: context, builder: (context) => CoverSelectionDialog( filter: filter, customEntry: customEntry, - customPackage: existingCover?.item2, - customColor: existingCover?.item3, + customPackage: existingCover?.$2, + customColor: existingCover?.$3, ), routeSettings: const RouteSettings(name: CoverSelectionDialog.routeName), ); diff --git a/test/model/collection_source_test.dart b/test/model/collection_source_test.dart index 7a0dee3bd..f21fcc516 100644 --- a/test/model/collection_source_test.dart +++ b/test/model/collection_source_test.dart @@ -1,5 +1,6 @@ import 'dart:async'; +import 'package:aves/l10n/l10n.dart'; import 'package:aves/model/availability.dart'; import 'package:aves/model/covers.dart'; import 'package:aves/model/db/db_metadata.dart'; @@ -201,7 +202,7 @@ void main() { await covers.set(filter: albumFilter, entryId: image1.id, packageName: null, color: null); expect(covers.count, 1); - expect(covers.of(albumFilter)?.item1, image1.id); + expect(covers.of(albumFilter)?.$1, image1.id); await covers.set(filter: albumFilter, entryId: null, packageName: null, color: null); expect(covers.count, 0); @@ -229,7 +230,7 @@ void main() { expect(favourites.count, 1); expect(image1.isFavourite, true); expect(covers.count, 1); - expect(covers.of(albumFilter)?.item1, image1.id); + expect(covers.of(albumFilter)?.$1, image1.id); }); test('favourites and covers are cleared when removing entries', () async { @@ -348,7 +349,7 @@ void main() { expect(favourites.count, 1); expect(image1.isFavourite, true); expect(covers.count, 1); - expect(covers.of(albumFilter)?.item1, image1.id); + expect(covers.of(albumFilter)?.$1, image1.id); }); testWidgets('unique album names', (tester) async { @@ -369,22 +370,26 @@ void main() { final source = await _initSource(); await tester.pumpWidget( - Builder( - builder: (context) { - expect(source.getAlbumDisplayName(context, '${FakeStorageService.primaryPath}Pictures/Elea/Zeno'), 'Elea/Zeno'); - expect(source.getAlbumDisplayName(context, '${FakeStorageService.primaryPath}Pictures/Citium/Zeno'), 'Citium/Zeno'); - expect(source.getAlbumDisplayName(context, '${FakeStorageService.primaryPath}Pictures/Cleanthes'), 'Cleanthes'); - expect(source.getAlbumDisplayName(context, '${FakeStorageService.primaryPath}Pictures/Chrysippus'), 'Chrysippus'); - expect(source.getAlbumDisplayName(context, '${FakeStorageService.removablePath}Pictures/Chrysippus'), 'Chrysippus (${FakeStorageService.removableDescription})'); - expect(source.getAlbumDisplayName(context, FakeStorageService.primaryRootAlbum), FakeStorageService.primaryDescription); - expect(source.getAlbumDisplayName(context, '${FakeStorageService.primaryPath}Pictures/Seneca'), 'Pictures/Seneca'); - expect(source.getAlbumDisplayName(context, '${FakeStorageService.primaryPath}Seneca'), 'Seneca'); - expect(source.getAlbumDisplayName(context, '${FakeStorageService.removablePath}Pictures/Cicero'), 'Cicero'); - expect(source.getAlbumDisplayName(context, '${FakeStorageService.removablePath}Marcus Aurelius'), 'Marcus Aurelius'); - expect(source.getAlbumDisplayName(context, '${FakeStorageService.primaryPath}Pictures/Hannah Arendt'), 'Hannah Arendt'); - expect(source.getAlbumDisplayName(context, '${FakeStorageService.primaryPath}Pictures/Arendt'), 'Arendt'); - return const Placeholder(); - }, + Localizations( + locale: AppLocalizations.supportedLocales.first, + delegates: AppLocalizations.localizationsDelegates, + child: Builder( + builder: (context) { + expect(source.getAlbumDisplayName(context, '${FakeStorageService.primaryPath}Pictures/Elea/Zeno'), 'Elea/Zeno'); + expect(source.getAlbumDisplayName(context, '${FakeStorageService.primaryPath}Pictures/Citium/Zeno'), 'Citium/Zeno'); + expect(source.getAlbumDisplayName(context, '${FakeStorageService.primaryPath}Pictures/Cleanthes'), 'Cleanthes'); + expect(source.getAlbumDisplayName(context, '${FakeStorageService.primaryPath}Pictures/Chrysippus'), 'Chrysippus'); + expect(source.getAlbumDisplayName(context, '${FakeStorageService.removablePath}Pictures/Chrysippus'), 'Chrysippus (${FakeStorageService.removableDescription})'); + expect(source.getAlbumDisplayName(context, FakeStorageService.primaryRootAlbum), FakeStorageService.primaryDescription); + expect(source.getAlbumDisplayName(context, '${FakeStorageService.primaryPath}Pictures/Seneca'), 'Pictures/Seneca'); + expect(source.getAlbumDisplayName(context, '${FakeStorageService.primaryPath}Seneca'), 'Seneca'); + expect(source.getAlbumDisplayName(context, '${FakeStorageService.removablePath}Pictures/Cicero'), 'Cicero'); + expect(source.getAlbumDisplayName(context, '${FakeStorageService.removablePath}Marcus Aurelius'), 'Marcus Aurelius'); + expect(source.getAlbumDisplayName(context, '${FakeStorageService.primaryPath}Pictures/Hannah Arendt'), 'Hannah Arendt'); + expect(source.getAlbumDisplayName(context, '${FakeStorageService.primaryPath}Pictures/Arendt'), 'Arendt'); + return const Placeholder(); + }, + ), ), ); }); diff --git a/test/utils/math_utils_test.dart b/test/utils/math_utils_test.dart index 8032d07c9..0d067bcd6 100644 --- a/test/utils/math_utils_test.dart +++ b/test/utils/math_utils_test.dart @@ -2,7 +2,6 @@ import 'dart:ui'; import 'package:aves/utils/math_utils.dart'; import 'package:test/test.dart'; -import 'package:tuple/tuple.dart'; void main() { test('highest power of 2 that is smaller than or equal to the number', () { @@ -29,8 +28,8 @@ void main() { }); test('segment intersection', () { - const s1 = Tuple2(Offset(1, 1), Offset(3, 2)); - const s2 = Tuple2(Offset(1, 4), Offset(2, -1)); + const s1 = (Offset(1, 1), Offset(3, 2)); + const s2 = (Offset(1, 4), Offset(2, -1)); expect(segmentIntersection(s1, s2), const Offset(17 / 11, 14 / 11)); }); }