mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2024-11-21 23:10:40 +00:00
fixed tests
This commit is contained in:
parent
4d02e71736
commit
fce8d0bb6a
16 changed files with 265 additions and 320 deletions
|
@ -48,7 +48,7 @@ void testE2E(String description) {
|
||||||
description,
|
description,
|
||||||
(tester) async {
|
(tester) async {
|
||||||
await tester.pumpApplication(
|
await tester.pumpApplication(
|
||||||
equipmentProfiles: [],
|
equipmentProfiles: {},
|
||||||
predefinedFilms: mockFilms.toFilmsMap(isUsed: true),
|
predefinedFilms: mockFilms.toFilmsMap(isUsed: true),
|
||||||
customFilms: {},
|
customFilms: {},
|
||||||
);
|
);
|
||||||
|
@ -58,7 +58,7 @@ void testE2E(String description) {
|
||||||
await tester.tapDescendantTextOf<SettingsScreen>(S.current.equipmentProfiles);
|
await tester.tapDescendantTextOf<SettingsScreen>(S.current.equipmentProfiles);
|
||||||
await tester.tap(find.byIcon(Icons.add_outlined).first);
|
await tester.tap(find.byIcon(Icons.add_outlined).first);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
await tester.setProfileName(mockEquipmentProfiles[0].name);
|
await tester.selectProfileName(mockEquipmentProfiles[0].name);
|
||||||
await tester.expandEquipmentProfileContainer(mockEquipmentProfiles[0].name);
|
await tester.expandEquipmentProfileContainer(mockEquipmentProfiles[0].name);
|
||||||
await tester.setIsoValues(0, mockEquipmentProfiles[0].isoValues);
|
await tester.setIsoValues(0, mockEquipmentProfiles[0].isoValues);
|
||||||
await tester.setNdValues(0, mockEquipmentProfiles[0].ndValues);
|
await tester.setNdValues(0, mockEquipmentProfiles[0].ndValues);
|
||||||
|
@ -72,7 +72,7 @@ void testE2E(String description) {
|
||||||
/// Create Praktica + Jupiter profile from Zenitar profile
|
/// Create Praktica + Jupiter profile from Zenitar profile
|
||||||
await tester.tap(find.byIcon(Icons.copy_outlined).first);
|
await tester.tap(find.byIcon(Icons.copy_outlined).first);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
await tester.setProfileName(mockEquipmentProfiles[1].name);
|
await tester.selectProfileName(mockEquipmentProfiles[1].name);
|
||||||
await tester.expandEquipmentProfileContainer(mockEquipmentProfiles[1].name);
|
await tester.expandEquipmentProfileContainer(mockEquipmentProfiles[1].name);
|
||||||
await tester.setApertureValues(1, mockEquipmentProfiles[1].apertureValues);
|
await tester.setApertureValues(1, mockEquipmentProfiles[1].apertureValues);
|
||||||
await tester.setZoomValue(1, mockEquipmentProfiles[1].lensZoom);
|
await tester.setZoomValue(1, mockEquipmentProfiles[1].lensZoom);
|
||||||
|
@ -152,7 +152,7 @@ extension EquipmentProfileActions on WidgetTester {
|
||||||
await pump(Dimens.durationM);
|
await pump(Dimens.durationM);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> setProfileName(String name) async {
|
Future<void> selectProfileName(String name) async {
|
||||||
await enterText(find.byType(TextField), name);
|
await enterText(find.byType(TextField), name);
|
||||||
await pump();
|
await pump();
|
||||||
await tapSaveButton();
|
await tapSaveButton();
|
||||||
|
|
|
@ -5,12 +5,12 @@ import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart';
|
||||||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
import 'package:mocktail/mocktail.dart';
|
import 'package:mocktail/mocktail.dart';
|
||||||
|
|
||||||
class _MockIAPStorageService extends Mock implements IAPStorageService {}
|
class _MockEquipmentProfilesStorageService extends Mock implements EquipmentProfilesStorageService {}
|
||||||
|
|
||||||
class _MockFilmsStorageService extends Mock implements FilmsStorageService {}
|
class _MockFilmsStorageService extends Mock implements FilmsStorageService {}
|
||||||
|
|
||||||
class MockIAPProviders extends StatefulWidget {
|
class MockIAPProviders extends StatefulWidget {
|
||||||
final List<EquipmentProfile>? equipmentProfiles;
|
final Map<String, EquipmentProfile> equipmentProfiles;
|
||||||
final String selectedEquipmentProfileId;
|
final String selectedEquipmentProfileId;
|
||||||
final Map<String, SelectableFilm<Film>> predefinedFilms;
|
final Map<String, SelectableFilm<Film>> predefinedFilms;
|
||||||
final Map<String, SelectableFilm<FilmExponential>> customFilms;
|
final Map<String, SelectableFilm<FilmExponential>> customFilms;
|
||||||
|
@ -18,14 +18,15 @@ class MockIAPProviders extends StatefulWidget {
|
||||||
final Widget child;
|
final Widget child;
|
||||||
|
|
||||||
MockIAPProviders({
|
MockIAPProviders({
|
||||||
this.equipmentProfiles = const [],
|
Map<String, EquipmentProfile>? equipmentProfiles,
|
||||||
this.selectedEquipmentProfileId = '',
|
this.selectedEquipmentProfileId = '',
|
||||||
Map<String, SelectableFilm<Film>>? predefinedFilms,
|
Map<String, SelectableFilm<Film>>? predefinedFilms,
|
||||||
Map<String, SelectableFilm<FilmExponential>>? customFilms,
|
Map<String, SelectableFilm<FilmExponential>>? customFilms,
|
||||||
String? selectedFilmId,
|
String? selectedFilmId,
|
||||||
required this.child,
|
required this.child,
|
||||||
super.key,
|
super.key,
|
||||||
}) : predefinedFilms = predefinedFilms ?? mockFilms.toFilmsMap(),
|
}) : equipmentProfiles = equipmentProfiles ?? mockEquipmentProfiles.toProfilesMap(),
|
||||||
|
predefinedFilms = predefinedFilms ?? mockFilms.toFilmsMap(),
|
||||||
customFilms = customFilms ?? mockFilms.toFilmsMap(),
|
customFilms = customFilms ?? mockFilms.toFilmsMap(),
|
||||||
selectedFilmId = selectedFilmId ?? const FilmStub().id;
|
selectedFilmId = selectedFilmId ?? const FilmStub().id;
|
||||||
|
|
||||||
|
@ -34,15 +35,18 @@ class MockIAPProviders extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _MockIAPProvidersState extends State<MockIAPProviders> {
|
class _MockIAPProvidersState extends State<MockIAPProviders> {
|
||||||
late final _MockIAPStorageService mockIAPStorageService;
|
late final _MockEquipmentProfilesStorageService mockEquipmentProfilesStorageService;
|
||||||
late final _MockFilmsStorageService mockFilmsStorageService;
|
late final _MockFilmsStorageService mockFilmsStorageService;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
mockIAPStorageService = _MockIAPStorageService();
|
mockEquipmentProfilesStorageService = _MockEquipmentProfilesStorageService();
|
||||||
when(() => mockIAPStorageService.equipmentProfiles).thenReturn(widget.equipmentProfiles ?? mockEquipmentProfiles);
|
when(() => mockEquipmentProfilesStorageService.init()).thenAnswer((_) async {});
|
||||||
when(() => mockIAPStorageService.selectedEquipmentProfileId).thenReturn(widget.selectedEquipmentProfileId);
|
when(() => mockEquipmentProfilesStorageService.getProfiles())
|
||||||
|
.thenAnswer((_) => Future.value(widget.equipmentProfiles));
|
||||||
|
when(() => mockEquipmentProfilesStorageService.selectedEquipmentProfileId)
|
||||||
|
.thenReturn(widget.selectedEquipmentProfileId);
|
||||||
|
|
||||||
mockFilmsStorageService = _MockFilmsStorageService();
|
mockFilmsStorageService = _MockFilmsStorageService();
|
||||||
when(() => mockFilmsStorageService.init()).thenAnswer((_) async {});
|
when(() => mockFilmsStorageService.init()).thenAnswer((_) async {});
|
||||||
|
@ -53,10 +57,10 @@ class _MockIAPProvidersState extends State<MockIAPProviders> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return EquipmentProfileProvider(
|
return EquipmentProfilesProvider(
|
||||||
storageService: mockIAPStorageService,
|
storageService: mockEquipmentProfilesStorageService,
|
||||||
child: FilmsProvider(
|
child: FilmsProvider(
|
||||||
filmsStorageService: mockFilmsStorageService,
|
storageService: mockFilmsStorageService,
|
||||||
child: widget.child,
|
child: widget.child,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -142,6 +146,10 @@ const mockFilms = [
|
||||||
_FilmMultiplying(id: '4', name: 'Mock film 4', iso: 1200, reciprocityMultiplier: 1.5),
|
_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> {
|
extension FilmMapper on List<Film> {
|
||||||
Map<String, ({T film, bool isUsed})> toFilmsMap<T extends Film>({bool isUsed = true}) =>
|
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))));
|
Map.fromEntries(map((e) => MapEntry(e.id, (film: e as T, isUsed: isUsed))));
|
||||||
|
|
|
@ -20,7 +20,7 @@ const mockPhotoEv100 = 8.3;
|
||||||
extension WidgetTesterCommonActions on WidgetTester {
|
extension WidgetTesterCommonActions on WidgetTester {
|
||||||
Future<void> pumpApplication({
|
Future<void> pumpApplication({
|
||||||
IAPProductStatus productStatus = IAPProductStatus.purchased,
|
IAPProductStatus productStatus = IAPProductStatus.purchased,
|
||||||
List<EquipmentProfile>? equipmentProfiles,
|
Map<String, EquipmentProfile>? equipmentProfiles,
|
||||||
String selectedEquipmentProfileId = '',
|
String selectedEquipmentProfileId = '',
|
||||||
Map<String, SelectableFilm<Film>>? predefinedFilms,
|
Map<String, SelectableFilm<Film>>? predefinedFilms,
|
||||||
Map<String, SelectableFilm<FilmExponential>>? customFilms,
|
Map<String, SelectableFilm<FilmExponential>>? customFilms,
|
||||||
|
|
|
@ -72,7 +72,7 @@ class _ApplicationWrapperState extends State<ApplicationWrapper> {
|
||||||
volumeEventsService: const VolumeEventsService(LocalPlatform()),
|
volumeEventsService: const VolumeEventsService(LocalPlatform()),
|
||||||
child: RemoteConfigProvider(
|
child: RemoteConfigProvider(
|
||||||
remoteConfigService: remoteConfigService,
|
remoteConfigService: remoteConfigService,
|
||||||
child: EquipmentProfileProvider(
|
child: EquipmentProfilesProvider(
|
||||||
storageService: equipmentProfilesStorageService,
|
storageService: equipmentProfilesStorageService,
|
||||||
onInitialized: equipmentProfilesStorageServiceCompleter.complete,
|
onInitialized: equipmentProfilesStorageServiceCompleter.complete,
|
||||||
child: FilmsProvider(
|
child: FilmsProvider(
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
enum NavigationRoutes {
|
enum NavigationRoutes {
|
||||||
meteringScreen,
|
meteringScreen,
|
||||||
settingsScreen,
|
settingsScreen,
|
||||||
filmsListScreen,
|
|
||||||
filmEditScreen,
|
|
||||||
equipmentProfilesListScreen,
|
equipmentProfilesListScreen,
|
||||||
equipmentProfileEditScreen,
|
equipmentProfileEditScreen,
|
||||||
|
filmsListScreen,
|
||||||
|
filmEditScreen,
|
||||||
proFeaturesScreen,
|
proFeaturesScreen,
|
||||||
timerScreen,
|
timerScreen,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,31 +1,11 @@
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:lightmeter/utils/context_utils.dart';
|
import 'package:lightmeter/utils/context_utils.dart';
|
||||||
import 'package:lightmeter/utils/selectable_provider.dart';
|
|
||||||
import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart';
|
import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart';
|
||||||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
|
|
||||||
class EquipmentProfileProvider extends StatefulWidget {
|
class EquipmentProfilesProvider extends StatefulWidget {
|
||||||
final EquipmentProfilesStorageService storageService;
|
static const EquipmentProfile defaultProfile = EquipmentProfile(
|
||||||
final VoidCallback? onInitialized;
|
|
||||||
final Widget child;
|
|
||||||
|
|
||||||
const EquipmentProfileProvider({
|
|
||||||
required this.storageService,
|
|
||||||
this.onInitialized,
|
|
||||||
required this.child,
|
|
||||||
super.key,
|
|
||||||
});
|
|
||||||
|
|
||||||
static EquipmentProfileProviderState of(BuildContext context) {
|
|
||||||
return context.findAncestorStateOfType<EquipmentProfileProviderState>()!;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<EquipmentProfileProvider> createState() => EquipmentProfileProviderState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class EquipmentProfileProviderState extends State<EquipmentProfileProvider> {
|
|
||||||
static const EquipmentProfile _defaultProfile = EquipmentProfile(
|
|
||||||
id: '',
|
id: '',
|
||||||
name: '',
|
name: '',
|
||||||
apertureValues: ApertureValue.values,
|
apertureValues: ApertureValue.values,
|
||||||
|
@ -34,10 +14,30 @@ class EquipmentProfileProviderState extends State<EquipmentProfileProvider> {
|
||||||
isoValues: IsoValue.values,
|
isoValues: IsoValue.values,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final EquipmentProfilesStorageService storageService;
|
||||||
|
final VoidCallback? onInitialized;
|
||||||
|
final Widget child;
|
||||||
|
|
||||||
|
const EquipmentProfilesProvider({
|
||||||
|
required this.storageService,
|
||||||
|
this.onInitialized,
|
||||||
|
required this.child,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
static EquipmentProfilesProviderState of(BuildContext context) {
|
||||||
|
return context.findAncestorStateOfType<EquipmentProfilesProviderState>()!;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<EquipmentProfilesProvider> createState() => EquipmentProfilesProviderState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class EquipmentProfilesProviderState extends State<EquipmentProfilesProvider> {
|
||||||
final Map<String, EquipmentProfile> _customProfiles = {};
|
final Map<String, EquipmentProfile> _customProfiles = {};
|
||||||
String _selectedId = '';
|
String _selectedId = '';
|
||||||
|
|
||||||
EquipmentProfile get _selectedProfile => _customProfiles[_selectedId] ?? _defaultProfile;
|
EquipmentProfile get _selectedProfile => _customProfiles[_selectedId] ?? EquipmentProfilesProvider.defaultProfile;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
@ -48,11 +48,8 @@ class EquipmentProfileProviderState extends State<EquipmentProfileProvider> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return EquipmentProfiles(
|
return EquipmentProfiles(
|
||||||
values: [
|
profiles: context.isPro ? _customProfiles : {},
|
||||||
_defaultProfile,
|
selected: context.isPro ? _selectedProfile : EquipmentProfilesProvider.defaultProfile,
|
||||||
if (context.isPro) ..._customProfiles.values,
|
|
||||||
],
|
|
||||||
selected: context.isPro ? _selectedProfile : _defaultProfile,
|
|
||||||
child: widget.child,
|
child: widget.child,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -64,15 +61,6 @@ class EquipmentProfileProviderState extends State<EquipmentProfileProvider> {
|
||||||
widget.onInitialized?.call();
|
widget.onInitialized?.call();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setProfile(EquipmentProfile data) {
|
|
||||||
if (_selectedId != data.id) {
|
|
||||||
setState(() {
|
|
||||||
_selectedId = data.id;
|
|
||||||
});
|
|
||||||
widget.storageService.selectedEquipmentProfileId = _selectedProfile.id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> addProfile(EquipmentProfile profile) async {
|
Future<void> addProfile(EquipmentProfile profile) async {
|
||||||
await widget.storageService.addProfile(profile);
|
await widget.storageService.addProfile(profile);
|
||||||
_customProfiles[profile.id] = profile;
|
_customProfiles[profile.id] = profile;
|
||||||
|
@ -98,32 +86,58 @@ class EquipmentProfileProviderState extends State<EquipmentProfileProvider> {
|
||||||
Future<void> deleteProfile(EquipmentProfile profile) async {
|
Future<void> deleteProfile(EquipmentProfile profile) async {
|
||||||
await widget.storageService.deleteProfile(profile.id);
|
await widget.storageService.deleteProfile(profile.id);
|
||||||
if (profile.id == _selectedId) {
|
if (profile.id == _selectedId) {
|
||||||
_selectedId = _defaultProfile.id;
|
_selectedId = EquipmentProfilesProvider.defaultProfile.id;
|
||||||
widget.storageService.selectedEquipmentProfileId = _defaultProfile.id;
|
widget.storageService.selectedEquipmentProfileId = EquipmentProfilesProvider.defaultProfile.id;
|
||||||
}
|
}
|
||||||
_customProfiles.remove(profile.id);
|
_customProfiles.remove(profile.id);
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void selectProfile(EquipmentProfile data) {
|
||||||
|
if (_selectedId != data.id) {
|
||||||
|
setState(() {
|
||||||
|
_selectedId = data.id;
|
||||||
|
});
|
||||||
|
widget.storageService.selectedEquipmentProfileId = _selectedProfile.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class EquipmentProfiles extends SelectableInheritedModel<EquipmentProfile> {
|
enum _EquipmentProfilesModelAspect {
|
||||||
|
profiles,
|
||||||
|
selected,
|
||||||
|
}
|
||||||
|
|
||||||
|
class EquipmentProfiles extends InheritedModel<_EquipmentProfilesModelAspect> {
|
||||||
|
final Map<String, EquipmentProfile> profiles;
|
||||||
|
final EquipmentProfile selected;
|
||||||
|
|
||||||
const EquipmentProfiles({
|
const EquipmentProfiles({
|
||||||
super.key,
|
required this.profiles,
|
||||||
required super.values,
|
required this.selected,
|
||||||
required super.selected,
|
|
||||||
required super.child,
|
required super.child,
|
||||||
});
|
});
|
||||||
|
|
||||||
/// [_defaultProfile] + profiles created by the user
|
/// _default + profiles create by the user
|
||||||
static List<EquipmentProfile> of(BuildContext context) {
|
static List<EquipmentProfile> of(BuildContext context) {
|
||||||
return InheritedModel.inheritFrom<EquipmentProfiles>(context, aspect: SelectableAspect.list)!.values;
|
final model =
|
||||||
|
InheritedModel.inheritFrom<EquipmentProfiles>(context, aspect: _EquipmentProfilesModelAspect.profiles)!;
|
||||||
|
return List.from([EquipmentProfilesProvider.defaultProfile, ...model.profiles.values]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static EquipmentProfile selectedOf(BuildContext context) {
|
static EquipmentProfile selectedOf(BuildContext context) {
|
||||||
return InheritedModel.inheritFrom<EquipmentProfiles>(
|
return InheritedModel.inheritFrom<EquipmentProfiles>(context, aspect: _EquipmentProfilesModelAspect.selected)!
|
||||||
context,
|
|
||||||
aspect: SelectableAspect.selected,
|
|
||||||
)!
|
|
||||||
.selected;
|
.selected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool updateShouldNotify(EquipmentProfiles _) => true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool updateShouldNotifyDependent(EquipmentProfiles oldWidget, Set<_EquipmentProfilesModelAspect> dependencies) {
|
||||||
|
return (dependencies.contains(_EquipmentProfilesModelAspect.selected) && oldWidget.selected != selected) ||
|
||||||
|
((dependencies.contains(_EquipmentProfilesModelAspect.profiles) ||
|
||||||
|
dependencies.contains(_EquipmentProfilesModelAspect.profiles)) &&
|
||||||
|
const DeepCollectionEquality().equals(oldWidget.profiles, profiles));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,22 +6,13 @@ import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
class EquipmentProfileEditBloc extends Bloc<EquipmentProfileEditEvent, EquipmentProfileEditState> {
|
class EquipmentProfileEditBloc extends Bloc<EquipmentProfileEditEvent, EquipmentProfileEditState> {
|
||||||
static const EquipmentProfile _defaultProfile = EquipmentProfile(
|
final EquipmentProfilesProviderState profilesProvider;
|
||||||
id: '',
|
|
||||||
name: '',
|
|
||||||
apertureValues: ApertureValue.values,
|
|
||||||
ndValues: NdValue.values,
|
|
||||||
shutterSpeedValues: ShutterSpeedValue.values,
|
|
||||||
isoValues: IsoValue.values,
|
|
||||||
);
|
|
||||||
|
|
||||||
final EquipmentProfileProviderState profilesProvider;
|
|
||||||
final EquipmentProfile _originalEquipmentProfile;
|
final EquipmentProfile _originalEquipmentProfile;
|
||||||
EquipmentProfile _newEquipmentProfile;
|
EquipmentProfile _newEquipmentProfile;
|
||||||
final bool _isEdit;
|
final bool _isEdit;
|
||||||
|
|
||||||
factory EquipmentProfileEditBloc(
|
factory EquipmentProfileEditBloc(
|
||||||
EquipmentProfileProviderState profilesProvider, {
|
EquipmentProfilesProviderState profilesProvider, {
|
||||||
required EquipmentProfile? profile,
|
required EquipmentProfile? profile,
|
||||||
required bool isEdit,
|
required bool isEdit,
|
||||||
}) =>
|
}) =>
|
||||||
|
@ -33,7 +24,7 @@ class EquipmentProfileEditBloc extends Bloc<EquipmentProfileEditEvent, Equipment
|
||||||
)
|
)
|
||||||
: EquipmentProfileEditBloc._(
|
: EquipmentProfileEditBloc._(
|
||||||
profilesProvider,
|
profilesProvider,
|
||||||
_defaultProfile,
|
EquipmentProfilesProvider.defaultProfile,
|
||||||
isEdit,
|
isEdit,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ class EquipmentProfileEditFlow extends StatelessWidget {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (_) => EquipmentProfileEditBloc(
|
create: (_) => EquipmentProfileEditBloc(
|
||||||
EquipmentProfileProvider.of(context),
|
EquipmentProfilesProvider.of(context),
|
||||||
profile: args.profile,
|
profile: args.profile,
|
||||||
isEdit: args.profile != null,
|
isEdit: args.profile != null,
|
||||||
),
|
),
|
||||||
|
|
|
@ -16,7 +16,7 @@ class EquipmentProfilePicker extends StatelessWidget {
|
||||||
selectedValue: EquipmentProfiles.selectedOf(context),
|
selectedValue: EquipmentProfiles.selectedOf(context),
|
||||||
values: EquipmentProfiles.of(context),
|
values: EquipmentProfiles.of(context),
|
||||||
itemTitleBuilder: (_, value) => Text(value.id.isEmpty ? S.of(context).none : value.name),
|
itemTitleBuilder: (_, value) => Text(value.id.isEmpty ? S.of(context).none : value.name),
|
||||||
onChanged: EquipmentProfileProvider.of(context).setProfile,
|
onChanged: EquipmentProfilesProvider.of(context).selectProfile,
|
||||||
closedChild: ReadingValueContainer.singleValue(
|
closedChild: ReadingValueContainer.singleValue(
|
||||||
value: ReadingValue(
|
value: ReadingValue(
|
||||||
label: S.of(context).equipmentProfile,
|
label: S.of(context).equipmentProfile,
|
||||||
|
|
|
@ -36,7 +36,7 @@ class MeteringScreenLayoutListTile extends StatelessWidget {
|
||||||
},
|
},
|
||||||
onSave: (value) {
|
onSave: (value) {
|
||||||
if (!value[MeteringScreenLayoutFeature.equipmentProfiles]!) {
|
if (!value[MeteringScreenLayoutFeature.equipmentProfiles]!) {
|
||||||
EquipmentProfileProvider.of(context).setProfile(EquipmentProfiles.of(context).first);
|
EquipmentProfilesProvider.of(context).selectProfile(EquipmentProfiles.of(context).first);
|
||||||
}
|
}
|
||||||
if (!value[MeteringScreenLayoutFeature.filmPicker]!) {
|
if (!value[MeteringScreenLayoutFeature.filmPicker]!) {
|
||||||
FilmsProvider.of(context).selectFilm(const FilmStub());
|
FilmsProvider.of(context).selectFilm(const FilmStub());
|
||||||
|
|
|
@ -108,7 +108,6 @@ class _GoldenTestApplicationMockState extends State<GoldenTestApplicationMock> {
|
||||||
],
|
],
|
||||||
child: _MockApplicationWrapper(
|
child: _MockApplicationWrapper(
|
||||||
child: MockIAPProviders(
|
child: MockIAPProviders(
|
||||||
equipmentProfiles: mockEquipmentProfiles,
|
|
||||||
selectedEquipmentProfileId: mockEquipmentProfiles.first.id,
|
selectedEquipmentProfileId: mockEquipmentProfiles.first.id,
|
||||||
selectedFilmId: mockFilms.first.id,
|
selectedFilmId: mockFilms.first.id,
|
||||||
child: Builder(
|
child: Builder(
|
||||||
|
|
|
@ -5,14 +5,29 @@ import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart';
|
||||||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
import 'package:mocktail/mocktail.dart';
|
import 'package:mocktail/mocktail.dart';
|
||||||
|
|
||||||
class _MockIAPStorageService extends Mock implements IAPStorageService {}
|
import '../../integration_test/mocks/paid_features_mock.dart';
|
||||||
|
|
||||||
|
class _MockEquipmentProfilesStorageService extends Mock implements EquipmentProfilesStorageService {}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
TestWidgetsFlutterBinding.ensureInitialized();
|
TestWidgetsFlutterBinding.ensureInitialized();
|
||||||
late _MockIAPStorageService storageService;
|
late _MockEquipmentProfilesStorageService storageService;
|
||||||
|
|
||||||
setUpAll(() {
|
setUpAll(() {
|
||||||
storageService = _MockIAPStorageService();
|
storageService = _MockEquipmentProfilesStorageService();
|
||||||
|
});
|
||||||
|
|
||||||
|
setUp(() {
|
||||||
|
registerFallbackValue(_customProfiles.first);
|
||||||
|
when(() => storageService.addProfile(any<EquipmentProfile>())).thenAnswer((_) async {});
|
||||||
|
when(
|
||||||
|
() => storageService.updateProfile(
|
||||||
|
id: any<String>(named: 'id'),
|
||||||
|
name: any<String>(named: 'name'),
|
||||||
|
),
|
||||||
|
).thenAnswer((_) async {});
|
||||||
|
when(() => storageService.deleteProfile(any<String>())).thenAnswer((_) async {});
|
||||||
|
when(() => storageService.getProfiles()).thenAnswer((_) => Future.value(_customProfiles.toProfilesMap()));
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() {
|
tearDown(() {
|
||||||
|
@ -29,35 +44,36 @@ void main() {
|
||||||
price: '0.0\$',
|
price: '0.0\$',
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
child: EquipmentProfileProvider(
|
child: EquipmentProfilesProvider(
|
||||||
storageService: storageService,
|
storageService: storageService,
|
||||||
child: const _Application(),
|
child: const _Application(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
}
|
}
|
||||||
|
|
||||||
void expectEquipmentProfilesCount(int count) {
|
void expectEquipmentProfilesCount(int count) {
|
||||||
expect(find.text('Equipment profiles count: $count'), findsOneWidget);
|
expect(find.text(_EquipmentProfilesCount.text(count)), findsOneWidget);
|
||||||
}
|
}
|
||||||
|
|
||||||
void expectSelectedEquipmentProfileName(String name) {
|
void expectSelectedEquipmentProfileName(String name) {
|
||||||
expect(find.text('Selected equipment profile: $name'), findsOneWidget);
|
expect(find.text(_SelectedEquipmentProfile.text(name)), findsOneWidget);
|
||||||
}
|
}
|
||||||
|
|
||||||
group(
|
group(
|
||||||
'EquipmentProfileProvider dependency on IAPProductStatus',
|
'EquipmentProfilesProvider dependency on IAPProductStatus',
|
||||||
() {
|
() {
|
||||||
setUp(() {
|
setUp(() {
|
||||||
when(() => storageService.selectedEquipmentProfileId).thenReturn(_customProfiles.first.id);
|
when(() => storageService.selectedEquipmentProfileId).thenReturn(_customProfiles.first.id);
|
||||||
when(() => storageService.equipmentProfiles).thenReturn(_customProfiles);
|
when(() => storageService.getProfiles()).thenAnswer((_) => Future.value(_customProfiles.toProfilesMap()));
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets(
|
testWidgets(
|
||||||
'IAPProductStatus.purchased - show all saved profiles',
|
'IAPProductStatus.purchased - show all saved profiles',
|
||||||
(tester) async {
|
(tester) async {
|
||||||
await pumpTestWidget(tester, IAPProductStatus.purchased);
|
await pumpTestWidget(tester, IAPProductStatus.purchased);
|
||||||
expectEquipmentProfilesCount(3);
|
expectEquipmentProfilesCount(_customProfiles.length + 1);
|
||||||
expectSelectedEquipmentProfileName(_customProfiles.first.name);
|
expectSelectedEquipmentProfileName(_customProfiles.first.name);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -82,203 +98,105 @@ void main() {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
group('EquipmentProfileProvider CRUD', () {
|
|
||||||
testWidgets(
|
testWidgets(
|
||||||
'Add',
|
'EquipmentProfilesProvider CRUD',
|
||||||
(tester) async {
|
(tester) async {
|
||||||
when(() => storageService.equipmentProfiles).thenReturn([]);
|
when(() => storageService.getProfiles()).thenAnswer((_) async => {});
|
||||||
when(() => storageService.selectedEquipmentProfileId).thenReturn('');
|
when(() => storageService.selectedEquipmentProfileId).thenReturn('');
|
||||||
|
|
||||||
await pumpTestWidget(tester, IAPProductStatus.purchased);
|
await pumpTestWidget(tester, IAPProductStatus.purchased);
|
||||||
expectEquipmentProfilesCount(1);
|
expectEquipmentProfilesCount(1);
|
||||||
expectSelectedEquipmentProfileName('');
|
expectSelectedEquipmentProfileName('');
|
||||||
|
|
||||||
await tester.tap(find.byKey(_Application.addProfileButtonKey));
|
/// Add first profile and verify
|
||||||
|
await tester.equipmentProfilesProvider.addProfile(_customProfiles.first);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
expectEquipmentProfilesCount(2);
|
expectEquipmentProfilesCount(2);
|
||||||
expectSelectedEquipmentProfileName('');
|
expectSelectedEquipmentProfileName('');
|
||||||
|
verify(() => storageService.addProfile(any<EquipmentProfile>())).called(1);
|
||||||
|
|
||||||
verifyNever(() => storageService.selectedEquipmentProfileId = '');
|
/// Add the other profiles and select the 1st one
|
||||||
verify(() => storageService.equipmentProfiles = any<List<EquipmentProfile>>()).called(1);
|
for (final profile in _customProfiles.skip(1)) {
|
||||||
},
|
await tester.equipmentProfilesProvider.addProfile(profile);
|
||||||
);
|
}
|
||||||
|
tester.equipmentProfilesProvider.selectProfile(_customProfiles.first);
|
||||||
testWidgets(
|
|
||||||
'Add from',
|
|
||||||
(tester) async {
|
|
||||||
when(() => storageService.equipmentProfiles).thenReturn(List.from(_customProfiles));
|
|
||||||
when(() => storageService.selectedEquipmentProfileId).thenReturn('');
|
|
||||||
|
|
||||||
await pumpTestWidget(tester, IAPProductStatus.purchased);
|
|
||||||
expectEquipmentProfilesCount(3);
|
|
||||||
expectSelectedEquipmentProfileName('');
|
|
||||||
|
|
||||||
await tester.tap(find.byKey(_Application.addFromProfileButtonKey(_customProfiles[0].id)));
|
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
expectEquipmentProfilesCount(4);
|
expectEquipmentProfilesCount(1 + _customProfiles.length);
|
||||||
expectSelectedEquipmentProfileName('');
|
expectSelectedEquipmentProfileName(_customProfiles.first.name);
|
||||||
|
|
||||||
|
/// Edit the selected profile
|
||||||
|
final updatedName = "${_customProfiles.first} updated";
|
||||||
|
await tester.equipmentProfilesProvider.updateProfile(_customProfiles.first.copyWith(name: updatedName));
|
||||||
|
await tester.pump();
|
||||||
|
expectEquipmentProfilesCount(1 + _customProfiles.length);
|
||||||
|
expectSelectedEquipmentProfileName(updatedName);
|
||||||
|
verify(() => storageService.updateProfile(id: _customProfiles.first.id, name: updatedName)).called(1);
|
||||||
|
|
||||||
|
/// Delete a non-selected profile
|
||||||
|
await tester.equipmentProfilesProvider.deleteProfile(_customProfiles.last);
|
||||||
|
await tester.pump();
|
||||||
|
expectEquipmentProfilesCount(1 + _customProfiles.length - 1);
|
||||||
|
expectSelectedEquipmentProfileName(updatedName);
|
||||||
verifyNever(() => storageService.selectedEquipmentProfileId = '');
|
verifyNever(() => storageService.selectedEquipmentProfileId = '');
|
||||||
verify(() => storageService.equipmentProfiles = any<List<EquipmentProfile>>()).called(1);
|
verify(() => storageService.deleteProfile(_customProfiles.last.id)).called(1);
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
testWidgets(
|
|
||||||
'Edit selected',
|
|
||||||
(tester) async {
|
|
||||||
when(() => storageService.equipmentProfiles).thenReturn(List.from(_customProfiles));
|
|
||||||
when(() => storageService.selectedEquipmentProfileId).thenReturn(_customProfiles[0].id);
|
|
||||||
|
|
||||||
await pumpTestWidget(tester, IAPProductStatus.purchased);
|
|
||||||
|
|
||||||
/// Change the name & limit ISO values of the both added profiles
|
|
||||||
await tester.tap(find.byKey(_Application.updateProfileButtonKey(_customProfiles[0].id)));
|
|
||||||
await tester.pumpAndSettle();
|
|
||||||
expectEquipmentProfilesCount(3);
|
|
||||||
expectSelectedEquipmentProfileName("${_customProfiles[0].name} updated");
|
|
||||||
|
|
||||||
verifyNever(() => storageService.selectedEquipmentProfileId = _customProfiles[0].id);
|
|
||||||
verify(() => storageService.equipmentProfiles = any<List<EquipmentProfile>>()).called(1);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
testWidgets(
|
|
||||||
'Delete selected',
|
|
||||||
(tester) async {
|
|
||||||
when(() => storageService.equipmentProfiles).thenReturn(List.from(_customProfiles));
|
|
||||||
when(() => storageService.selectedEquipmentProfileId).thenReturn(_customProfiles[0].id);
|
|
||||||
|
|
||||||
await pumpTestWidget(tester, IAPProductStatus.purchased);
|
|
||||||
expectEquipmentProfilesCount(3);
|
|
||||||
expectSelectedEquipmentProfileName(_customProfiles[0].name);
|
|
||||||
|
|
||||||
/// Delete the selected profile
|
/// Delete the selected profile
|
||||||
await tester.tap(find.byKey(_Application.deleteProfileButtonKey(_customProfiles[0].id)));
|
await tester.equipmentProfilesProvider.deleteProfile(_customProfiles.first);
|
||||||
await tester.pumpAndSettle();
|
await tester.pump();
|
||||||
expectEquipmentProfilesCount(2);
|
expectEquipmentProfilesCount(1 + _customProfiles.length - 2);
|
||||||
expectSelectedEquipmentProfileName('');
|
expectSelectedEquipmentProfileName('');
|
||||||
|
|
||||||
verify(() => storageService.selectedEquipmentProfileId = '').called(1);
|
verify(() => storageService.selectedEquipmentProfileId = '').called(1);
|
||||||
verify(() => storageService.equipmentProfiles = any<List<EquipmentProfile>>()).called(1);
|
verify(() => storageService.deleteProfile(_customProfiles.first.id)).called(1);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
testWidgets(
|
extension on WidgetTester {
|
||||||
'Delete not selected',
|
EquipmentProfilesProviderState get equipmentProfilesProvider {
|
||||||
(tester) async {
|
final BuildContext context = element(find.byType(_Application));
|
||||||
when(() => storageService.equipmentProfiles).thenReturn(List.from(_customProfiles));
|
return EquipmentProfilesProvider.of(context);
|
||||||
when(() => storageService.selectedEquipmentProfileId).thenReturn(_customProfiles[0].id);
|
}
|
||||||
|
|
||||||
await pumpTestWidget(tester, IAPProductStatus.purchased);
|
|
||||||
expectEquipmentProfilesCount(3);
|
|
||||||
expectSelectedEquipmentProfileName(_customProfiles[0].name);
|
|
||||||
|
|
||||||
/// Delete the not selected profile
|
|
||||||
await tester.tap(find.byKey(_Application.deleteProfileButtonKey(_customProfiles[1].id)));
|
|
||||||
await tester.pumpAndSettle();
|
|
||||||
expectEquipmentProfilesCount(2);
|
|
||||||
expectSelectedEquipmentProfileName(_customProfiles[0].name);
|
|
||||||
|
|
||||||
verifyNever(() => storageService.selectedEquipmentProfileId = '');
|
|
||||||
verify(() => storageService.equipmentProfiles = any<List<EquipmentProfile>>()).called(1);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
testWidgets(
|
|
||||||
'Select',
|
|
||||||
(tester) async {
|
|
||||||
when(() => storageService.equipmentProfiles).thenReturn(List.from(_customProfiles));
|
|
||||||
when(() => storageService.selectedEquipmentProfileId).thenReturn('');
|
|
||||||
|
|
||||||
await pumpTestWidget(tester, IAPProductStatus.purchased);
|
|
||||||
expectEquipmentProfilesCount(3);
|
|
||||||
expectSelectedEquipmentProfileName('');
|
|
||||||
|
|
||||||
/// Select the 1st custom profile
|
|
||||||
await tester.tap(find.byKey(_Application.setProfileButtonKey(_customProfiles[0].id)));
|
|
||||||
await tester.pumpAndSettle();
|
|
||||||
expectEquipmentProfilesCount(3);
|
|
||||||
expectSelectedEquipmentProfileName(_customProfiles[0].name);
|
|
||||||
|
|
||||||
verify(() => storageService.selectedEquipmentProfileId = _customProfiles[0].id).called(1);
|
|
||||||
verifyNever(() => storageService.equipmentProfiles = any<List<EquipmentProfile>>());
|
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class _Application extends StatelessWidget {
|
class _Application extends StatelessWidget {
|
||||||
const _Application();
|
const _Application();
|
||||||
|
|
||||||
static ValueKey get addProfileButtonKey => const ValueKey('addProfileButtonKey');
|
|
||||||
static ValueKey addFromProfileButtonKey(String id) => ValueKey('addFromProfileButtonKey$id');
|
|
||||||
static ValueKey setProfileButtonKey(String id) => ValueKey('setProfileButtonKey$id');
|
|
||||||
static ValueKey updateProfileButtonKey(String id) => ValueKey('updateProfileButtonKey$id');
|
|
||||||
static ValueKey deleteProfileButtonKey(String id) => ValueKey('deleteProfileButtonKey$id');
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MaterialApp(
|
return const MaterialApp(
|
||||||
home: Scaffold(
|
home: Scaffold(
|
||||||
appBar: AppBar(title: const Text('IAPProviders test')),
|
|
||||||
body: Center(
|
body: Center(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Text("Equipment profiles count: ${EquipmentProfiles.of(context).length}"),
|
_EquipmentProfilesCount(),
|
||||||
Text("Selected equipment profile: ${EquipmentProfiles.selectedOf(context).name}"),
|
_SelectedEquipmentProfile(),
|
||||||
ElevatedButton(
|
|
||||||
key: addProfileButtonKey,
|
|
||||||
onPressed: () {
|
|
||||||
EquipmentProfileProvider.of(context).addProfile('Test added');
|
|
||||||
},
|
|
||||||
child: const Text("Add"),
|
|
||||||
),
|
|
||||||
...EquipmentProfiles.of(context).map((e) => _equipmentProfilesCrudRow(context, e)),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Widget _equipmentProfilesCrudRow(BuildContext context, EquipmentProfile profile) {
|
class _EquipmentProfilesCount extends StatelessWidget {
|
||||||
return Row(
|
static String text(int count) => "Profiles count: $count";
|
||||||
children: [
|
|
||||||
ElevatedButton(
|
const _EquipmentProfilesCount();
|
||||||
key: setProfileButtonKey(profile.id),
|
|
||||||
onPressed: () {
|
@override
|
||||||
EquipmentProfileProvider.of(context).setProfile(profile);
|
Widget build(BuildContext context) {
|
||||||
},
|
return Text(text(EquipmentProfiles.of(context).length));
|
||||||
child: const Text("Set"),
|
}
|
||||||
),
|
}
|
||||||
ElevatedButton(
|
|
||||||
key: addFromProfileButtonKey(profile.id),
|
class _SelectedEquipmentProfile extends StatelessWidget {
|
||||||
onPressed: () {
|
static String text(String name) => "Selected profile: $name}";
|
||||||
EquipmentProfileProvider.of(context).addProfile('Test from ${profile.name}', profile);
|
|
||||||
},
|
const _SelectedEquipmentProfile();
|
||||||
child: const Text("Add from"),
|
|
||||||
),
|
@override
|
||||||
ElevatedButton(
|
Widget build(BuildContext context) {
|
||||||
key: updateProfileButtonKey(profile.id),
|
return Text(text(EquipmentProfiles.selectedOf(context).name));
|
||||||
onPressed: () {
|
|
||||||
EquipmentProfileProvider.of(context).updateProfile(
|
|
||||||
profile.copyWith(
|
|
||||||
name: '${profile.name} updated',
|
|
||||||
isoValues: _customProfiles.first.isoValues,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: const Text("Update"),
|
|
||||||
),
|
|
||||||
ElevatedButton(
|
|
||||||
key: deleteProfileButtonKey(profile.id),
|
|
||||||
onPressed: () {
|
|
||||||
EquipmentProfileProvider.of(context).deleteProfile(profile);
|
|
||||||
},
|
|
||||||
child: const Text("Delete"),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,25 +9,24 @@ class _MockFilmsStorageService extends Mock implements FilmsStorageService {}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
TestWidgetsFlutterBinding.ensureInitialized();
|
TestWidgetsFlutterBinding.ensureInitialized();
|
||||||
late _MockFilmsStorageService mockFilmsStorageService;
|
late _MockFilmsStorageService storageService;
|
||||||
|
|
||||||
setUpAll(() {
|
setUpAll(() {
|
||||||
mockFilmsStorageService = _MockFilmsStorageService();
|
storageService = _MockFilmsStorageService();
|
||||||
});
|
});
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
registerFallbackValue(mockCustomFilms.first);
|
registerFallbackValue(mockCustomFilms.first);
|
||||||
when(() => mockFilmsStorageService.toggleFilm(any<Film>(), any<bool>())).thenAnswer((_) async {});
|
when(() => storageService.toggleFilm(any<Film>(), any<bool>())).thenAnswer((_) async {});
|
||||||
when(() => mockFilmsStorageService.addFilm(any<FilmExponential>())).thenAnswer((_) async {});
|
when(() => storageService.addFilm(any<FilmExponential>())).thenAnswer((_) async {});
|
||||||
when(() => mockFilmsStorageService.updateFilm(any<FilmExponential>())).thenAnswer((_) async {});
|
when(() => storageService.updateFilm(any<FilmExponential>())).thenAnswer((_) async {});
|
||||||
when(() => mockFilmsStorageService.deleteFilm(any<FilmExponential>())).thenAnswer((_) async {});
|
when(() => storageService.deleteFilm(any<FilmExponential>())).thenAnswer((_) async {});
|
||||||
when(() => mockFilmsStorageService.getPredefinedFilms())
|
when(() => storageService.getPredefinedFilms()).thenAnswer((_) => Future.value(mockPredefinedFilms.toFilmsMap()));
|
||||||
.thenAnswer((_) => Future.value(mockPredefinedFilms.toFilmsMap()));
|
when(() => storageService.getCustomFilms()).thenAnswer((_) => Future.value(mockCustomFilms.toFilmsMap()));
|
||||||
when(() => mockFilmsStorageService.getCustomFilms()).thenAnswer((_) => Future.value(mockCustomFilms.toFilmsMap()));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() {
|
tearDown(() {
|
||||||
reset(mockFilmsStorageService);
|
reset(storageService);
|
||||||
});
|
});
|
||||||
|
|
||||||
Future<void> pumpTestWidget(WidgetTester tester, IAPProductStatus productStatus) async {
|
Future<void> pumpTestWidget(WidgetTester tester, IAPProductStatus productStatus) async {
|
||||||
|
@ -41,7 +40,7 @@ void main() {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
child: FilmsProvider(
|
child: FilmsProvider(
|
||||||
filmsStorageService: mockFilmsStorageService,
|
storageService: storageService,
|
||||||
child: const _Application(),
|
child: const _Application(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -69,11 +68,10 @@ void main() {
|
||||||
'FilmsProvider dependency on IAPProductStatus',
|
'FilmsProvider dependency on IAPProductStatus',
|
||||||
() {
|
() {
|
||||||
setUp(() {
|
setUp(() {
|
||||||
when(() => mockFilmsStorageService.selectedFilmId).thenReturn(mockPredefinedFilms.first.id);
|
when(() => storageService.selectedFilmId).thenReturn(mockPredefinedFilms.first.id);
|
||||||
when(() => mockFilmsStorageService.getPredefinedFilms())
|
when(() => storageService.getPredefinedFilms())
|
||||||
.thenAnswer((_) => Future.value(mockPredefinedFilms.toFilmsMap()));
|
.thenAnswer((_) => Future.value(mockPredefinedFilms.toFilmsMap()));
|
||||||
when(() => mockFilmsStorageService.getCustomFilms())
|
when(() => storageService.getCustomFilms()).thenAnswer((_) => Future.value(mockCustomFilms.toFilmsMap()));
|
||||||
.thenAnswer((_) => Future.value(mockCustomFilms.toFilmsMap()));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets(
|
testWidgets(
|
||||||
|
@ -117,7 +115,7 @@ void main() {
|
||||||
testWidgets(
|
testWidgets(
|
||||||
'toggle predefined film',
|
'toggle predefined film',
|
||||||
(tester) async {
|
(tester) async {
|
||||||
when(() => mockFilmsStorageService.selectedFilmId).thenReturn(mockPredefinedFilms.first.id);
|
when(() => storageService.selectedFilmId).thenReturn(mockPredefinedFilms.first.id);
|
||||||
await pumpTestWidget(tester, IAPProductStatus.purchased);
|
await pumpTestWidget(tester, IAPProductStatus.purchased);
|
||||||
expectPredefinedFilmsCount(mockPredefinedFilms.length);
|
expectPredefinedFilmsCount(mockPredefinedFilms.length);
|
||||||
expectCustomFilmsCount(mockCustomFilms.length);
|
expectCustomFilmsCount(mockCustomFilms.length);
|
||||||
|
@ -131,15 +129,15 @@ void main() {
|
||||||
expectFilmsInUseCount(mockPredefinedFilms.length - 1 + mockCustomFilms.length + 1);
|
expectFilmsInUseCount(mockPredefinedFilms.length - 1 + mockCustomFilms.length + 1);
|
||||||
expectSelectedFilmName('');
|
expectSelectedFilmName('');
|
||||||
|
|
||||||
verify(() => mockFilmsStorageService.toggleFilm(mockPredefinedFilms.first, false)).called(1);
|
verify(() => storageService.toggleFilm(mockPredefinedFilms.first, false)).called(1);
|
||||||
verify(() => mockFilmsStorageService.selectedFilmId = '').called(1);
|
verify(() => storageService.selectedFilmId = '').called(1);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
testWidgets(
|
testWidgets(
|
||||||
'toggle custom film',
|
'toggle custom film',
|
||||||
(tester) async {
|
(tester) async {
|
||||||
when(() => mockFilmsStorageService.selectedFilmId).thenReturn(mockCustomFilms.first.id);
|
when(() => storageService.selectedFilmId).thenReturn(mockCustomFilms.first.id);
|
||||||
await pumpTestWidget(tester, IAPProductStatus.purchased);
|
await pumpTestWidget(tester, IAPProductStatus.purchased);
|
||||||
expectPredefinedFilmsCount(mockPredefinedFilms.length);
|
expectPredefinedFilmsCount(mockPredefinedFilms.length);
|
||||||
expectCustomFilmsCount(mockCustomFilms.length);
|
expectCustomFilmsCount(mockCustomFilms.length);
|
||||||
|
@ -153,8 +151,8 @@ void main() {
|
||||||
expectFilmsInUseCount(mockPredefinedFilms.length - 1 + mockCustomFilms.length + 1);
|
expectFilmsInUseCount(mockPredefinedFilms.length - 1 + mockCustomFilms.length + 1);
|
||||||
expectSelectedFilmName('');
|
expectSelectedFilmName('');
|
||||||
|
|
||||||
verify(() => mockFilmsStorageService.toggleFilm(mockCustomFilms.first, false)).called(1);
|
verify(() => storageService.toggleFilm(mockCustomFilms.first, false)).called(1);
|
||||||
verify(() => mockFilmsStorageService.selectedFilmId = '').called(1);
|
verify(() => storageService.selectedFilmId = '').called(1);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -163,7 +161,7 @@ void main() {
|
||||||
testWidgets(
|
testWidgets(
|
||||||
'selectFilm',
|
'selectFilm',
|
||||||
(tester) async {
|
(tester) async {
|
||||||
when(() => mockFilmsStorageService.selectedFilmId).thenReturn('');
|
when(() => storageService.selectedFilmId).thenReturn('');
|
||||||
await pumpTestWidget(tester, IAPProductStatus.purchased);
|
await pumpTestWidget(tester, IAPProductStatus.purchased);
|
||||||
expectSelectedFilmName('');
|
expectSelectedFilmName('');
|
||||||
|
|
||||||
|
@ -175,16 +173,16 @@ void main() {
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
expectSelectedFilmName(mockCustomFilms.first.name);
|
expectSelectedFilmName(mockCustomFilms.first.name);
|
||||||
|
|
||||||
verify(() => mockFilmsStorageService.selectedFilmId = mockPredefinedFilms.first.id).called(1);
|
verify(() => storageService.selectedFilmId = mockPredefinedFilms.first.id).called(1);
|
||||||
verify(() => mockFilmsStorageService.selectedFilmId = mockCustomFilms.first.id).called(1);
|
verify(() => storageService.selectedFilmId = mockCustomFilms.first.id).called(1);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
testWidgets(
|
testWidgets(
|
||||||
'Custom film CRUD',
|
'Custom film CRUD',
|
||||||
(tester) async {
|
(tester) async {
|
||||||
when(() => mockFilmsStorageService.selectedFilmId).thenReturn('');
|
when(() => storageService.selectedFilmId).thenReturn('');
|
||||||
when(() => mockFilmsStorageService.getCustomFilms()).thenAnswer((_) => Future.value({}));
|
when(() => storageService.getCustomFilms()).thenAnswer((_) => Future.value({}));
|
||||||
await pumpTestWidget(tester, IAPProductStatus.purchased);
|
await pumpTestWidget(tester, IAPProductStatus.purchased);
|
||||||
expectPredefinedFilmsCount(mockPredefinedFilms.length);
|
expectPredefinedFilmsCount(mockPredefinedFilms.length);
|
||||||
expectCustomFilmsCount(0);
|
expectCustomFilmsCount(0);
|
||||||
|
@ -199,16 +197,16 @@ void main() {
|
||||||
expectCustomFilmsCount(1);
|
expectCustomFilmsCount(1);
|
||||||
expectFilmsInUseCount(mockPredefinedFilms.length + 1 + 1);
|
expectFilmsInUseCount(mockPredefinedFilms.length + 1 + 1);
|
||||||
expectSelectedFilmName(mockCustomFilms.first.name);
|
expectSelectedFilmName(mockCustomFilms.first.name);
|
||||||
verify(() => mockFilmsStorageService.addFilm(mockCustomFilms.first)).called(1);
|
verify(() => storageService.addFilm(mockCustomFilms.first)).called(1);
|
||||||
verify(() => mockFilmsStorageService.toggleFilm(mockCustomFilms.first, true)).called(1);
|
verify(() => storageService.toggleFilm(mockCustomFilms.first, true)).called(1);
|
||||||
verify(() => mockFilmsStorageService.selectedFilmId = mockCustomFilms.first.id).called(1);
|
verify(() => storageService.selectedFilmId = mockCustomFilms.first.id).called(1);
|
||||||
|
|
||||||
const editedFilmName = 'Edited custom film 2x';
|
const editedFilmName = 'Edited custom film 2x';
|
||||||
final editedFilm = mockCustomFilms.first.copyWith(name: editedFilmName);
|
final editedFilm = mockCustomFilms.first.copyWith(name: editedFilmName);
|
||||||
await tester.filmsProvider.updateCustomFilm(editedFilm);
|
await tester.filmsProvider.updateCustomFilm(editedFilm);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
expectSelectedFilmName(editedFilm.name);
|
expectSelectedFilmName(editedFilm.name);
|
||||||
verify(() => mockFilmsStorageService.updateFilm(editedFilm)).called(1);
|
verify(() => storageService.updateFilm(editedFilm)).called(1);
|
||||||
|
|
||||||
await tester.filmsProvider.deleteCustomFilm(editedFilm);
|
await tester.filmsProvider.deleteCustomFilm(editedFilm);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
@ -216,8 +214,8 @@ void main() {
|
||||||
expectCustomFilmsCount(0);
|
expectCustomFilmsCount(0);
|
||||||
expectFilmsInUseCount(mockPredefinedFilms.length + 0 + 1);
|
expectFilmsInUseCount(mockPredefinedFilms.length + 0 + 1);
|
||||||
expectSelectedFilmName('');
|
expectSelectedFilmName('');
|
||||||
verify(() => mockFilmsStorageService.deleteFilm(editedFilm)).called(1);
|
verify(() => storageService.deleteFilm(editedFilm)).called(1);
|
||||||
verify(() => mockFilmsStorageService.selectedFilmId = '').called(1);
|
verify(() => storageService.selectedFilmId = '').called(1);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,18 +7,19 @@ import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart';
|
||||||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
import 'package:mocktail/mocktail.dart';
|
import 'package:mocktail/mocktail.dart';
|
||||||
|
|
||||||
|
import '../../../../../../integration_test/mocks/paid_features_mock.dart';
|
||||||
import '../../../../../application_mock.dart';
|
import '../../../../../application_mock.dart';
|
||||||
import 'utils.dart';
|
import 'utils.dart';
|
||||||
|
|
||||||
class _MockIAPStorageService extends Mock implements IAPStorageService {}
|
class _MockEquipmentProfilesStorageService extends Mock implements EquipmentProfilesStorageService {}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
late final _MockIAPStorageService mockIAPStorageService;
|
late final _MockEquipmentProfilesStorageService storageService;
|
||||||
|
|
||||||
setUpAll(() {
|
setUpAll(() {
|
||||||
mockIAPStorageService = _MockIAPStorageService();
|
storageService = _MockEquipmentProfilesStorageService();
|
||||||
when(() => mockIAPStorageService.equipmentProfiles).thenReturn(_mockEquipmentProfiles);
|
when(() => storageService.getProfiles()).thenAnswer((_) async => _mockEquipmentProfiles.toProfilesMap());
|
||||||
when(() => mockIAPStorageService.selectedEquipmentProfileId).thenReturn('');
|
when(() => storageService.selectedEquipmentProfileId).thenReturn('');
|
||||||
});
|
});
|
||||||
|
|
||||||
Future<void> pumpApplication(WidgetTester tester) async {
|
Future<void> pumpApplication(WidgetTester tester) async {
|
||||||
|
@ -31,8 +32,8 @@ void main() {
|
||||||
price: '0.0\$',
|
price: '0.0\$',
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
child: EquipmentProfileProvider(
|
child: EquipmentProfilesProvider(
|
||||||
storageService: mockIAPStorageService,
|
storageService: storageService,
|
||||||
child: const WidgetTestApplicationMock(
|
child: const WidgetTestApplicationMock(
|
||||||
child: Row(children: [Expanded(child: EquipmentProfilePicker())]),
|
child: Row(children: [Expanded(child: EquipmentProfilePicker())]),
|
||||||
),
|
),
|
||||||
|
@ -59,7 +60,7 @@ void main() {
|
||||||
testWidgets(
|
testWidgets(
|
||||||
'None',
|
'None',
|
||||||
(tester) async {
|
(tester) async {
|
||||||
when(() => mockIAPStorageService.selectedEquipmentProfileId).thenReturn('');
|
when(() => storageService.selectedEquipmentProfileId).thenReturn('');
|
||||||
await pumpApplication(tester);
|
await pumpApplication(tester);
|
||||||
expectReadingValueContainerText(S.current.none);
|
expectReadingValueContainerText(S.current.none);
|
||||||
await tester.openAnimatedPicker<EquipmentProfilePicker>();
|
await tester.openAnimatedPicker<EquipmentProfilePicker>();
|
||||||
|
@ -70,7 +71,7 @@ void main() {
|
||||||
testWidgets(
|
testWidgets(
|
||||||
'Praktica + Zenitar',
|
'Praktica + Zenitar',
|
||||||
(tester) async {
|
(tester) async {
|
||||||
when(() => mockIAPStorageService.selectedEquipmentProfileId).thenReturn(_mockEquipmentProfiles.first.id);
|
when(() => storageService.selectedEquipmentProfileId).thenReturn(_mockEquipmentProfiles.first.id);
|
||||||
await pumpApplication(tester);
|
await pumpApplication(tester);
|
||||||
expectReadingValueContainerText(_mockEquipmentProfiles.first.name);
|
expectReadingValueContainerText(_mockEquipmentProfiles.first.name);
|
||||||
await tester.openAnimatedPicker<EquipmentProfilePicker>();
|
await tester.openAnimatedPicker<EquipmentProfilePicker>();
|
||||||
|
|
|
@ -36,7 +36,7 @@ void main() {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
child: FilmsProvider(
|
child: FilmsProvider(
|
||||||
filmsStorageService: mockFilmsStorageService,
|
storageService: mockFilmsStorageService,
|
||||||
child: const WidgetTestApplicationMock(
|
child: const WidgetTestApplicationMock(
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
|
|
|
@ -6,16 +6,29 @@ import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart';
|
||||||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
import 'package:mocktail/mocktail.dart';
|
import 'package:mocktail/mocktail.dart';
|
||||||
|
|
||||||
|
import '../../../../integration_test/mocks/paid_features_mock.dart';
|
||||||
import '../../../function_mock.dart';
|
import '../../../function_mock.dart';
|
||||||
|
|
||||||
class _MockIAPStorageService extends Mock implements IAPStorageService {}
|
class _MockEquipmentProfilesStorageService extends Mock implements EquipmentProfilesStorageService {}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
TestWidgetsFlutterBinding.ensureInitialized();
|
TestWidgetsFlutterBinding.ensureInitialized();
|
||||||
final storageService = _MockIAPStorageService();
|
final storageService = _MockEquipmentProfilesStorageService();
|
||||||
final equipmentProfileProviderKey = GlobalKey<EquipmentProfileProviderState>();
|
|
||||||
final onDidChangeDependencies = MockValueChanged<EquipmentProfile>();
|
final onDidChangeDependencies = MockValueChanged<EquipmentProfile>();
|
||||||
|
|
||||||
|
setUp(() {
|
||||||
|
registerFallbackValue(_customProfiles.first);
|
||||||
|
when(() => storageService.addProfile(any<EquipmentProfile>())).thenAnswer((_) async {});
|
||||||
|
when(
|
||||||
|
() => storageService.updateProfile(
|
||||||
|
id: any<String>(named: 'id'),
|
||||||
|
name: any<String>(named: 'name'),
|
||||||
|
),
|
||||||
|
).thenAnswer((_) async {});
|
||||||
|
when(() => storageService.deleteProfile(any<String>())).thenAnswer((_) async {});
|
||||||
|
when(() => storageService.getProfiles()).thenAnswer((_) => Future.value(_customProfiles.toProfilesMap()));
|
||||||
|
});
|
||||||
|
|
||||||
tearDown(() {
|
tearDown(() {
|
||||||
reset(onDidChangeDependencies);
|
reset(onDidChangeDependencies);
|
||||||
reset(storageService);
|
reset(storageService);
|
||||||
|
@ -31,8 +44,7 @@ void main() {
|
||||||
price: '0.0\$',
|
price: '0.0\$',
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
child: EquipmentProfileProvider(
|
child: EquipmentProfilesProvider(
|
||||||
key: equipmentProfileProviderKey,
|
|
||||||
storageService: storageService,
|
storageService: storageService,
|
||||||
child: MaterialApp(
|
child: MaterialApp(
|
||||||
home: EquipmentProfileListener(
|
home: EquipmentProfileListener(
|
||||||
|
@ -48,11 +60,10 @@ void main() {
|
||||||
testWidgets(
|
testWidgets(
|
||||||
'Trigger `onDidChangeDependencies` by selecting a new profile',
|
'Trigger `onDidChangeDependencies` by selecting a new profile',
|
||||||
(tester) async {
|
(tester) async {
|
||||||
when(() => storageService.equipmentProfiles).thenReturn(List.from(_customProfiles));
|
|
||||||
when(() => storageService.selectedEquipmentProfileId).thenReturn('');
|
when(() => storageService.selectedEquipmentProfileId).thenReturn('');
|
||||||
await pumpTestWidget(tester);
|
await pumpTestWidget(tester);
|
||||||
|
|
||||||
equipmentProfileProviderKey.currentState!.setProfile(_customProfiles[0]);
|
tester.equipmentProfilesProvider.selectProfile(_customProfiles[0]);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
verify(() => onDidChangeDependencies.onChanged(_customProfiles[0])).called(1);
|
verify(() => onDidChangeDependencies.onChanged(_customProfiles[0])).called(1);
|
||||||
},
|
},
|
||||||
|
@ -61,18 +72,17 @@ void main() {
|
||||||
testWidgets(
|
testWidgets(
|
||||||
'Trigger `onDidChangeDependencies` by updating the selected profile',
|
'Trigger `onDidChangeDependencies` by updating the selected profile',
|
||||||
(tester) async {
|
(tester) async {
|
||||||
when(() => storageService.equipmentProfiles).thenReturn(List.from(_customProfiles));
|
|
||||||
when(() => storageService.selectedEquipmentProfileId).thenReturn(_customProfiles[0].id);
|
when(() => storageService.selectedEquipmentProfileId).thenReturn(_customProfiles[0].id);
|
||||||
await pumpTestWidget(tester);
|
await pumpTestWidget(tester);
|
||||||
|
|
||||||
final updatedProfile1 = _customProfiles[0].copyWith(name: 'Test 1 updated');
|
final updatedProfile1 = _customProfiles[0].copyWith(name: 'Test 1 updated');
|
||||||
equipmentProfileProviderKey.currentState!.updateProfile(updatedProfile1);
|
await tester.equipmentProfilesProvider.updateProfile(updatedProfile1);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
verify(() => onDidChangeDependencies.onChanged(updatedProfile1)).called(1);
|
verify(() => onDidChangeDependencies.onChanged(updatedProfile1)).called(1);
|
||||||
|
|
||||||
/// Verify that updating the not selected profile doesn't trigger the callback
|
/// Verify that updating the not selected profile doesn't trigger the callback
|
||||||
final updatedProfile2 = _customProfiles[1].copyWith(name: 'Test 2 updated');
|
final updatedProfile2 = _customProfiles[1].copyWith(name: 'Test 2 updated');
|
||||||
equipmentProfileProviderKey.currentState!.updateProfile(updatedProfile2);
|
await tester.equipmentProfilesProvider.updateProfile(updatedProfile2);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
verifyNever(() => onDidChangeDependencies.onChanged(updatedProfile2));
|
verifyNever(() => onDidChangeDependencies.onChanged(updatedProfile2));
|
||||||
},
|
},
|
||||||
|
@ -81,18 +91,24 @@ void main() {
|
||||||
testWidgets(
|
testWidgets(
|
||||||
"Don't trigger `onDidChangeDependencies` by updating the unselected profile",
|
"Don't trigger `onDidChangeDependencies` by updating the unselected profile",
|
||||||
(tester) async {
|
(tester) async {
|
||||||
when(() => storageService.equipmentProfiles).thenReturn(List.from(_customProfiles));
|
|
||||||
when(() => storageService.selectedEquipmentProfileId).thenReturn(_customProfiles[0].id);
|
when(() => storageService.selectedEquipmentProfileId).thenReturn(_customProfiles[0].id);
|
||||||
await pumpTestWidget(tester);
|
await pumpTestWidget(tester);
|
||||||
|
|
||||||
final updatedProfile2 = _customProfiles[1].copyWith(name: 'Test 2 updated');
|
final updatedProfile2 = _customProfiles[1].copyWith(name: 'Test 2 updated');
|
||||||
equipmentProfileProviderKey.currentState!.updateProfile(updatedProfile2);
|
await tester.equipmentProfilesProvider.updateProfile(updatedProfile2);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
verifyNever(() => onDidChangeDependencies.onChanged(updatedProfile2));
|
verifyNever(() => onDidChangeDependencies.onChanged(updatedProfile2));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension on WidgetTester {
|
||||||
|
EquipmentProfilesProviderState get equipmentProfilesProvider {
|
||||||
|
final BuildContext context = element(find.byType(MaterialApp));
|
||||||
|
return EquipmentProfilesProvider.of(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final List<EquipmentProfile> _customProfiles = [
|
final List<EquipmentProfile> _customProfiles = [
|
||||||
const EquipmentProfile(
|
const EquipmentProfile(
|
||||||
id: '1',
|
id: '1',
|
||||||
|
|
Loading…
Reference in a new issue