mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2024-11-23 16:00:41 +00:00
30418a9cfd
* integrated `EquipmentProfilesStorageService` * implemented `EquipmentProfileEditScreen` * added equipment profiles screens to navigation * fixed tests * fixed splashscreen removal * replaced old `EquipmentProfilesScreen` * typo * use outlined icons * fixed storage mock for integration tests * recovered copy feature for profiles * added profile deletion to e2e test * added translations * added film translations * wip * add ability to toggle equipment profiles * lints * fixed tests * sync with iap rename * use `Toggleable` from resources * use iap 2.1.0 * use outlined edit icon
194 lines
7 KiB
Dart
194 lines
7 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:lightmeter/providers/equipment_profile_provider.dart';
|
|
import 'package:lightmeter/providers/films_provider.dart';
|
|
import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart';
|
|
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
|
import 'package:mocktail/mocktail.dart';
|
|
|
|
class _MockEquipmentProfilesStorageService extends Mock implements EquipmentProfilesStorageService {}
|
|
|
|
class _MockFilmsStorageService extends Mock implements FilmsStorageService {}
|
|
|
|
class MockIAPProviders extends StatefulWidget {
|
|
final TogglableMap<EquipmentProfile> equipmentProfiles;
|
|
final String selectedEquipmentProfileId;
|
|
final TogglableMap<Film> predefinedFilms;
|
|
final TogglableMap<FilmExponential> customFilms;
|
|
final String selectedFilmId;
|
|
final Widget child;
|
|
|
|
MockIAPProviders({
|
|
TogglableMap<EquipmentProfile>? equipmentProfiles,
|
|
this.selectedEquipmentProfileId = '',
|
|
TogglableMap<Film>? predefinedFilms,
|
|
TogglableMap<FilmExponential>? customFilms,
|
|
String? selectedFilmId,
|
|
required this.child,
|
|
super.key,
|
|
}) : equipmentProfiles = equipmentProfiles ?? mockEquipmentProfiles.toTogglableMap(),
|
|
predefinedFilms = predefinedFilms ?? mockFilms.toTogglableMap(),
|
|
customFilms = customFilms ?? mockFilms.toTogglableMap(),
|
|
selectedFilmId = selectedFilmId ?? const FilmStub().id;
|
|
|
|
@override
|
|
State<MockIAPProviders> createState() => _MockIAPProvidersState();
|
|
}
|
|
|
|
class _MockIAPProvidersState extends State<MockIAPProviders> {
|
|
late final _MockEquipmentProfilesStorageService mockEquipmentProfilesStorageService;
|
|
late final _MockFilmsStorageService mockFilmsStorageService;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
registerFallbackValue(defaultEquipmentProfile);
|
|
mockEquipmentProfilesStorageService = _MockEquipmentProfilesStorageService();
|
|
when(() => mockEquipmentProfilesStorageService.init()).thenAnswer((_) async {});
|
|
when(() => mockEquipmentProfilesStorageService.getProfiles())
|
|
.thenAnswer((_) => Future.value(widget.equipmentProfiles));
|
|
when(() => mockEquipmentProfilesStorageService.selectedEquipmentProfileId)
|
|
.thenReturn(widget.selectedEquipmentProfileId);
|
|
when(() => mockEquipmentProfilesStorageService.addProfile(any<EquipmentProfile>())).thenAnswer((_) async {});
|
|
when(
|
|
() => mockEquipmentProfilesStorageService.updateProfile(
|
|
id: any<String>(named: 'id'),
|
|
name: any<String>(named: 'name'),
|
|
),
|
|
).thenAnswer((_) async {});
|
|
when(() => mockEquipmentProfilesStorageService.deleteProfile(any<String>())).thenAnswer((_) async {});
|
|
|
|
mockFilmsStorageService = _MockFilmsStorageService();
|
|
when(() => mockFilmsStorageService.init()).thenAnswer((_) async {});
|
|
when(() => mockFilmsStorageService.getPredefinedFilms()).thenAnswer((_) => Future.value(widget.predefinedFilms));
|
|
when(() => mockFilmsStorageService.getCustomFilms()).thenAnswer((_) => Future.value(widget.customFilms));
|
|
when(() => mockFilmsStorageService.selectedFilmId).thenReturn(widget.selectedFilmId);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return EquipmentProfilesProvider(
|
|
storageService: mockEquipmentProfilesStorageService,
|
|
child: FilmsProvider(
|
|
storageService: mockFilmsStorageService,
|
|
child: widget.child,
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
const defaultEquipmentProfile = EquipmentProfile(
|
|
id: '',
|
|
name: '',
|
|
apertureValues: ApertureValue.values,
|
|
ndValues: NdValue.values,
|
|
shutterSpeedValues: ShutterSpeedValue.values,
|
|
isoValues: IsoValue.values,
|
|
);
|
|
|
|
final mockEquipmentProfiles = [
|
|
EquipmentProfile(
|
|
id: '1',
|
|
name: 'Praktica + Zenitar',
|
|
apertureValues: ApertureValue.values.sublist(
|
|
ApertureValue.values.indexOf(const ApertureValue(1.7, StopType.half)),
|
|
ApertureValue.values.indexOf(const ApertureValue(16, StopType.full)) + 1,
|
|
),
|
|
ndValues: const [
|
|
NdValue(0),
|
|
NdValue(2),
|
|
NdValue(4),
|
|
NdValue(8),
|
|
],
|
|
shutterSpeedValues: ShutterSpeedValue.values.sublist(
|
|
ShutterSpeedValue.values.indexOf(const ShutterSpeedValue(1000, true, StopType.full)),
|
|
ShutterSpeedValue.values.indexOf(const ShutterSpeedValue(1, false, StopType.full)) + 1,
|
|
),
|
|
isoValues: const [
|
|
IsoValue(50, StopType.full),
|
|
IsoValue(100, StopType.full),
|
|
IsoValue(200, StopType.full),
|
|
IsoValue(250, StopType.third),
|
|
IsoValue(400, StopType.full),
|
|
IsoValue(500, StopType.third),
|
|
IsoValue(800, StopType.full),
|
|
IsoValue(1600, StopType.full),
|
|
IsoValue(3200, StopType.full),
|
|
],
|
|
lensZoom: 1.91,
|
|
),
|
|
EquipmentProfile(
|
|
id: '2',
|
|
name: 'Praktica + Jupiter',
|
|
apertureValues: ApertureValue.values.sublist(
|
|
ApertureValue.values.indexOf(const ApertureValue(3.5, StopType.third)),
|
|
ApertureValue.values.indexOf(const ApertureValue(22, StopType.full)) + 1,
|
|
),
|
|
ndValues: const [
|
|
NdValue(0),
|
|
NdValue(2),
|
|
NdValue(4),
|
|
NdValue(8),
|
|
],
|
|
shutterSpeedValues: ShutterSpeedValue.values.sublist(
|
|
ShutterSpeedValue.values.indexOf(const ShutterSpeedValue(1000, true, StopType.full)),
|
|
ShutterSpeedValue.values.indexOf(const ShutterSpeedValue(1, false, StopType.full)) + 1,
|
|
),
|
|
isoValues: const [
|
|
IsoValue(50, StopType.full),
|
|
IsoValue(100, StopType.full),
|
|
IsoValue(200, StopType.full),
|
|
IsoValue(250, StopType.third),
|
|
IsoValue(400, StopType.full),
|
|
IsoValue(500, StopType.third),
|
|
IsoValue(800, StopType.full),
|
|
IsoValue(1600, StopType.full),
|
|
IsoValue(3200, StopType.full),
|
|
],
|
|
lensZoom: 5.02,
|
|
),
|
|
];
|
|
|
|
const mockFilms = [
|
|
_FilmMultiplying(id: '1', name: 'Mock film 1', iso: 100, reciprocityMultiplier: 2),
|
|
_FilmMultiplying(id: '2', name: 'Mock film 2', iso: 400, reciprocityMultiplier: 2),
|
|
_FilmMultiplying(id: '3', name: 'Mock film 3', iso: 800, reciprocityMultiplier: 3),
|
|
_FilmMultiplying(id: '4', name: 'Mock film 4', iso: 1200, reciprocityMultiplier: 1.5),
|
|
];
|
|
|
|
class _FilmMultiplying extends FilmExponential {
|
|
final double reciprocityMultiplier;
|
|
|
|
const _FilmMultiplying({
|
|
String? id,
|
|
required String name,
|
|
required super.iso,
|
|
required this.reciprocityMultiplier,
|
|
}) : super(id: id ?? name, name: 'Mock film $iso x$reciprocityMultiplier', exponent: 1);
|
|
|
|
@override
|
|
ShutterSpeedValue reciprocityFailure(ShutterSpeedValue shutterSpeed) {
|
|
if (shutterSpeed.isFraction) {
|
|
return shutterSpeed;
|
|
} else {
|
|
return ShutterSpeedValue(
|
|
shutterSpeed.rawValue * reciprocityMultiplier,
|
|
shutterSpeed.isFraction,
|
|
shutterSpeed.stopType,
|
|
);
|
|
}
|
|
}
|
|
|
|
@override
|
|
bool operator ==(Object other) {
|
|
if (identical(this, other)) return true;
|
|
if (other.runtimeType != runtimeType) return false;
|
|
return other is _FilmMultiplying &&
|
|
other.id == id &&
|
|
other.name == name &&
|
|
other.iso == iso &&
|
|
other.reciprocityMultiplier == reciprocityMultiplier;
|
|
}
|
|
|
|
@override
|
|
int get hashCode => Object.hash(id, name, iso, reciprocityMultiplier, runtimeType);
|
|
}
|