This commit is contained in:
Vadim 2024-11-11 13:00:09 +01:00
parent 57fbeeb88f
commit 7d1c1ebc9f
13 changed files with 47 additions and 51 deletions

View file

@ -1,7 +1,7 @@
import 'package:flutter/foundation.dart';
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
typedef SelectableFilm<T extends Film> = ({T film, bool isUsed});
typedef SelectableValue<T extends Film> = ({T film, bool isUsed});
class FilmsStorageService {
FilmsStorageService();
@ -22,11 +22,11 @@ class FilmsStorageService {
Future<void> deleteFilm(FilmExponential _) async {}
Future<Map<String, SelectableFilm<Film>>> getPredefinedFilms() async {
Future<Map<String, SelectableValue<Film>>> getPredefinedFilms() async {
return const {};
}
Future<Map<String, SelectableFilm<FilmExponential>>> getCustomFilms() async {
Future<Map<String, SelectableValue<FilmExponential>>> getCustomFilms() async {
return const {};
}
}

View file

@ -18,6 +18,7 @@ import 'package:lightmeter/screens/settings/components/shared/dialog_range_picke
import 'package:lightmeter/screens/settings/screen_settings.dart';
import 'package:lightmeter/utils/double_to_zoom.dart';
import 'package:lightmeter/utils/platform_utils.dart';
import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart';
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
import 'package:meta/meta.dart';
import 'package:shared_preferences/shared_preferences.dart';
@ -49,7 +50,7 @@ void testE2E(String description) {
(tester) async {
await tester.pumpApplication(
equipmentProfiles: {},
predefinedFilms: mockFilms.toFilmsMap(isUsed: true),
predefinedFilms: mockFilms.toSelectableMap(),
customFilms: {},
);

View file

@ -10,24 +10,24 @@ class _MockEquipmentProfilesStorageService extends Mock implements EquipmentProf
class _MockFilmsStorageService extends Mock implements FilmsStorageService {}
class MockIAPProviders extends StatefulWidget {
final Map<String, EquipmentProfile> equipmentProfiles;
final SelectableMap<EquipmentProfile> equipmentProfiles;
final String selectedEquipmentProfileId;
final Map<String, SelectableFilm<Film>> predefinedFilms;
final Map<String, SelectableFilm<FilmExponential>> customFilms;
final Map<String, SelectableValue<Film>> predefinedFilms;
final Map<String, SelectableValue<FilmExponential>> customFilms;
final String selectedFilmId;
final Widget child;
MockIAPProviders({
Map<String, EquipmentProfile>? equipmentProfiles,
SelectableMap<EquipmentProfile>? equipmentProfiles,
this.selectedEquipmentProfileId = '',
Map<String, SelectableFilm<Film>>? predefinedFilms,
Map<String, SelectableFilm<FilmExponential>>? customFilms,
Map<String, SelectableValue<Film>>? predefinedFilms,
Map<String, SelectableValue<FilmExponential>>? customFilms,
String? selectedFilmId,
required this.child,
super.key,
}) : equipmentProfiles = equipmentProfiles ?? mockEquipmentProfiles.toProfilesMap(),
predefinedFilms = predefinedFilms ?? mockFilms.toFilmsMap(),
customFilms = customFilms ?? mockFilms.toFilmsMap(),
}) : equipmentProfiles = equipmentProfiles ?? mockEquipmentProfiles.toSelectableMap(),
predefinedFilms = predefinedFilms ?? mockFilms.toSelectableMap(),
customFilms = customFilms ?? mockFilms.toSelectableMap(),
selectedFilmId = selectedFilmId ?? const FilmStub().id;
@override
@ -155,15 +155,6 @@ const mockFilms = [
_FilmMultiplying(id: '4', name: 'Mock film 4', iso: 1200, reciprocityMultiplier: 1.5),
];
extension EquipmentProfileMapper on List<EquipmentProfile> {
Map<String, EquipmentProfile> toProfilesMap() => Map.fromEntries(map((e) => MapEntry(e.id, e)));
}
extension FilmMapper on List<Film> {
Map<String, ({T film, bool isUsed})> toFilmsMap<T extends Film>({bool isUsed = true}) =>
Map.fromEntries(map((e) => MapEntry(e.id, (film: e as T, isUsed: isUsed))));
}
class _FilmMultiplying extends FilmExponential {
final double reciprocityMultiplier;

View file

@ -20,10 +20,10 @@ const mockPhotoEv100 = 8.3;
extension WidgetTesterCommonActions on WidgetTester {
Future<void> pumpApplication({
IAPProductStatus productStatus = IAPProductStatus.purchased,
Map<String, EquipmentProfile>? equipmentProfiles,
SelectableMap<EquipmentProfile>? equipmentProfiles,
String selectedEquipmentProfileId = '',
Map<String, SelectableFilm<Film>>? predefinedFilms,
Map<String, SelectableFilm<FilmExponential>>? customFilms,
Map<String, SelectableValue<Film>>? predefinedFilms,
Map<String, SelectableValue<FilmExponential>>? customFilms,
String selectedFilmId = '',
}) async {
await pumpWidget(

View file

@ -34,7 +34,7 @@ class EquipmentProfilesProvider extends StatefulWidget {
}
class EquipmentProfilesProviderState extends State<EquipmentProfilesProvider> {
final Map<String, EquipmentProfile> _customProfiles = {};
final SelectableMap<EquipmentProfile> _customProfiles = {};
String _selectedId = '';
EquipmentProfile get _selectedProfile => _customProfiles[_selectedId] ?? EquipmentProfilesProvider.defaultProfile;

View file

@ -25,11 +25,11 @@ class FilmsProvider extends StatefulWidget {
}
class FilmsProviderState extends State<FilmsProvider> {
final Map<String, SelectableFilm<Film>> predefinedFilms = {};
final Map<String, SelectableFilm<FilmExponential>> customFilms = {};
final Map<String, SelectableValue<Film>> predefinedFilms = {};
final Map<String, SelectableValue<FilmExponential>> customFilms = {};
String _selectedId = '';
Film get _selectedFilm => customFilms[_selectedId]?.film ?? predefinedFilms[_selectedId]?.film ?? const FilmStub();
Film get _selectedFilm => customFilms[_selectedId]?.value ?? predefinedFilms[_selectedId]?.value ?? const FilmStub();
@override
void initState() {
@ -60,9 +60,9 @@ class FilmsProviderState extends State<FilmsProvider> {
Future<void> toggleFilm(Film film, bool enabled) async {
if (predefinedFilms.containsKey(film.id)) {
predefinedFilms[film.id] = (film: film, isUsed: enabled);
predefinedFilms[film.id] = (value: film, isUsed: enabled);
} else if (customFilms.containsKey(film.id)) {
customFilms[film.id] = (film: film as FilmExponential, isUsed: enabled);
customFilms[film.id] = (value: film as FilmExponential, isUsed: enabled);
} else {
return;
}
@ -84,13 +84,13 @@ class FilmsProviderState extends State<FilmsProvider> {
Future<void> addCustomFilm(FilmExponential film) async {
// ignore: avoid_redundant_argument_values
await widget.storageService.addFilm(film, isUsed: true);
customFilms[film.id] = (film: film, isUsed: true);
customFilms[film.id] = (value: film, isUsed: true);
setState(() {});
}
Future<void> updateCustomFilm(FilmExponential film) async {
await widget.storageService.updateFilm(film);
customFilms[film.id] = (film: film, isUsed: customFilms[film.id]!.isUsed);
customFilms[film.id] = (value: film, isUsed: customFilms[film.id]!.isUsed);
setState(() {});
}
@ -121,10 +121,10 @@ enum _FilmsModelAspect {
}
class Films extends InheritedModel<_FilmsModelAspect> {
final Map<String, SelectableFilm<Film>> predefinedFilms;
final Map<String, SelectableValue<Film>> predefinedFilms;
@protected
final Map<String, SelectableFilm<FilmExponential>> customFilms;
final Map<String, SelectableValue<FilmExponential>> customFilms;
final Film selected;
const Films({
@ -138,7 +138,7 @@ class Films extends InheritedModel<_FilmsModelAspect> {
return InheritedModel.inheritFrom<Films>(context, aspect: _FilmsModelAspect.predefinedFilms)!
.predefinedFilms
.values
.map((value) => value.film)
.map((value) => value.value)
.toList();
}
@ -146,7 +146,7 @@ class Films extends InheritedModel<_FilmsModelAspect> {
return InheritedModel.inheritFrom<Films>(context, aspect: _FilmsModelAspect.customFilms)!
.customFilms
.values
.map((value) => value.film)
.map((value) => value.value)
.toList();
}
@ -155,8 +155,8 @@ class Films extends InheritedModel<_FilmsModelAspect> {
final model = InheritedModel.inheritFrom<Films>(context, aspect: _FilmsModelAspect.filmsInUse)!;
return [
const FilmStub(),
...model.customFilms.values.where((e) => e.isUsed).map((e) => e.film),
...model.predefinedFilms.values.where((e) => e.isUsed).map((e) => e.film),
...model.customFilms.values.where((e) => e.isUsed).map((e) => e.value),
...model.predefinedFilms.values.where((e) => e.isUsed).map((e) => e.value),
];
}

View file

@ -89,9 +89,12 @@ class _EquipmentProfilesListBuilder extends StatelessWidget {
top: index == 0 ? Dimens.paddingM : 0.0,
bottom: index == values.length - 1 ? Dimens.paddingM : 0.0,
),
child: ListTile(
child: CheckboxListTile(
title: Text(values[index].name),
trailing: IconButton(
controlAffinity: ListTileControlAffinity.leading,
value: false,
onChanged: (value) {},
secondary: IconButton(
onPressed: () => onEdit(values[index]),
icon: const Icon(Icons.edit),
),

View file

@ -23,6 +23,7 @@ import 'package:lightmeter/screens/settings/screen_settings.dart';
import 'package:lightmeter/screens/shared/animated_circular_button/widget_button_circular_animated.dart';
import 'package:lightmeter/screens/timer/screen_timer.dart';
import 'package:lightmeter/utils/platform_utils.dart';
import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart';
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
import 'package:shared_preferences/shared_preferences.dart';
@ -92,7 +93,7 @@ void main() {
testWidgets('Generate light theme screenshots', (tester) async {
await mockSharedPrefs(theme: ThemeType.light, color: _lightThemeColor);
await tester.pumpApplication(
predefinedFilms: [_mockFilm].toFilmsMap(),
predefinedFilms: [_mockFilm].toSelectableMap(),
customFilms: {},
selectedFilmId: _mockFilm.id,
);
@ -132,7 +133,7 @@ void main() {
(tester) async {
await mockSharedPrefs(theme: ThemeType.dark, color: _darkThemeColor);
await tester.pumpApplication(
predefinedFilms: [_mockFilm].toFilmsMap(),
predefinedFilms: [_mockFilm].toSelectableMap(),
customFilms: {},
selectedFilmId: _mockFilm.id,
);
@ -157,7 +158,7 @@ void main() {
color: _lightThemeColor,
);
await tester.pumpApplication(
predefinedFilms: [_mockFilm].toFilmsMap(),
predefinedFilms: [_mockFilm].toSelectableMap(),
customFilms: {},
selectedFilmId: _mockFilm.id,
);

View file

@ -27,7 +27,7 @@ void main() {
),
).thenAnswer((_) async {});
when(() => storageService.deleteProfile(any<String>())).thenAnswer((_) async {});
when(() => storageService.getProfiles()).thenAnswer((_) => Future.value(_customProfiles.toProfilesMap()));
when(() => storageService.getProfiles()).thenAnswer((_) => Future.value(_customProfiles.toSelectableMap()));
});
tearDown(() {
@ -66,7 +66,7 @@ void main() {
() {
setUp(() {
when(() => storageService.selectedEquipmentProfileId).thenReturn(_customProfiles.first.id);
when(() => storageService.getProfiles()).thenAnswer((_) => Future.value(_customProfiles.toProfilesMap()));
when(() => storageService.getProfiles()).thenAnswer((_) => Future.value(_customProfiles.toSelectableMap()));
});
testWidgets(

View file

@ -305,6 +305,6 @@ const mockCustomFilms = [
];
extension on List<Film> {
Map<String, ({T film, bool isUsed})> toFilmsMap<T extends Film>() =>
Map.fromEntries(map((e) => MapEntry(e.id, (film: e as T, isUsed: true))));
Map<String, ({T value, bool isUsed})> toFilmsMap<T extends Film>() =>
Map.fromEntries(map((e) => MapEntry(e.id, (value: e as T, isUsed: true))));
}

View file

@ -18,7 +18,7 @@ void main() {
setUpAll(() {
storageService = _MockEquipmentProfilesStorageService();
when(() => storageService.getProfiles()).thenAnswer((_) async => _mockEquipmentProfiles.toProfilesMap());
when(() => storageService.getProfiles()).thenAnswer((_) async => _mockEquipmentProfiles.toSelectableMap());
when(() => storageService.selectedEquipmentProfileId).thenReturn('');
});

View file

@ -18,7 +18,7 @@ void main() {
setUpAll(() {
mockFilmsStorageService = _MockFilmsStorageService();
when(() => mockFilmsStorageService.getPredefinedFilms()).thenAnswer(
(_) => Future.value(Map.fromEntries(_films.map((e) => MapEntry(e.id, (film: e, isUsed: true))))),
(_) => Future.value(Map.fromEntries(_films.map((e) => MapEntry(e.id, (value: e, isUsed: true))))),
);
when(() => mockFilmsStorageService.getCustomFilms()).thenAnswer(
(_) => Future.value({}),

View file

@ -26,7 +26,7 @@ void main() {
),
).thenAnswer((_) async {});
when(() => storageService.deleteProfile(any<String>())).thenAnswer((_) async {});
when(() => storageService.getProfiles()).thenAnswer((_) => Future.value(_customProfiles.toProfilesMap()));
when(() => storageService.getProfiles()).thenAnswer((_) => Future.value(_customProfiles.toSelectableMap()));
});
tearDown(() {