fixed light sensor platform mocks

This commit is contained in:
Vadim 2023-10-18 15:18:59 +02:00
parent 24804a119e
commit 043439b71f
3 changed files with 179 additions and 123 deletions

View file

@ -7,7 +7,6 @@ import 'package:lightmeter/data/models/ev_source_type.dart';
import 'package:lightmeter/data/models/exposure_pair.dart'; import 'package:lightmeter/data/models/exposure_pair.dart';
import 'package:lightmeter/data/shared_prefs_service.dart'; import 'package:lightmeter/data/shared_prefs_service.dart';
import 'package:lightmeter/generated/l10n.dart'; import 'package:lightmeter/generated/l10n.dart';
import 'package:lightmeter/screens/metering/components/bottom_controls/components/measure_button/widget_button_measure.dart';
import 'package:lightmeter/screens/metering/components/camera_container/widget_container_camera.dart'; import 'package:lightmeter/screens/metering/components/camera_container/widget_container_camera.dart';
import 'package:lightmeter/screens/metering/components/light_sensor_container/widget_container_light_sensor.dart'; import 'package:lightmeter/screens/metering/components/light_sensor_container/widget_container_light_sensor.dart';
import 'package:lightmeter/screens/metering/components/shared/exposure_pairs_list/widget_list_exposure_pairs.dart'; import 'package:lightmeter/screens/metering/components/shared/exposure_pairs_list/widget_list_exposure_pairs.dart';
@ -15,7 +14,6 @@ import 'package:lightmeter/screens/metering/components/shared/readings_container
import 'package:lightmeter/screens/metering/components/shared/readings_container/components/film_picker/widget_picker_film.dart'; import 'package:lightmeter/screens/metering/components/shared/readings_container/components/film_picker/widget_picker_film.dart';
import 'package:lightmeter/screens/metering/components/shared/readings_container/components/iso_picker/widget_picker_iso.dart'; import 'package:lightmeter/screens/metering/components/shared/readings_container/components/iso_picker/widget_picker_iso.dart';
import 'package:lightmeter/screens/metering/components/shared/readings_container/components/nd_picker/widget_picker_nd.dart'; import 'package:lightmeter/screens/metering/components/shared/readings_container/components/nd_picker/widget_picker_nd.dart';
import 'package:lightmeter/screens/metering/components/shared/readings_container/components/shared/animated_dialog_picker/components/dialog_picker/widget_picker_dialog.dart';
import 'package:lightmeter/screens/metering/screen_metering.dart'; import 'package:lightmeter/screens/metering/screen_metering.dart';
import 'package:lightmeter/screens/shared/icon_placeholder/widget_icon_placeholder.dart'; import 'package:lightmeter/screens/shared/icon_placeholder/widget_icon_placeholder.dart';
import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart'; import 'package:m3_lightmeter_iap/m3_lightmeter_iap.dart';
@ -24,6 +22,7 @@ import 'package:shared_preferences/shared_preferences.dart';
import 'mocks/paid_features_mock.dart'; import 'mocks/paid_features_mock.dart';
import 'utils/expectations.dart'; import 'utils/expectations.dart';
import 'utils/metering_picker_test.dart';
import 'utils/platform_channel_mock.dart'; import 'utils/platform_channel_mock.dart';
import 'utils/widget_tester_actions.dart'; import 'utils/widget_tester_actions.dart';
@ -40,9 +39,17 @@ const mockPhotoSlowestExposurePair = ExposurePair(mockPhotoSlowestAperture, mock
void main() { void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized(); IntegrationTestWidgetsFlutterBinding.ensureInitialized();
tearDown(() {
SharedPreferences.resetStatic();
});
group( group(
'[Light sensor availability]', '[Light sensor availability]',
() { () {
tearDown(() {
resetLightSensorAvilability();
});
testWidgets( testWidgets(
'Android - has sensor', 'Android - has sensor',
(tester) async { (tester) async {
@ -112,7 +119,7 @@ void main() {
expect(find.descendant(of: firstPairRow, matching: find.text(shutterSpeed)), findsOneWidget); expect(find.descendant(of: firstPairRow, matching: find.text(shutterSpeed)), findsOneWidget);
} }
setUpAll(() { setUp(() {
SharedPreferences.setMockInitialValues({UserPreferencesService.evSourceTypeKey: EvSourceType.camera.index}); SharedPreferences.setMockInitialValues({UserPreferencesService.evSourceTypeKey: EvSourceType.camera.index});
}); });
@ -185,118 +192,83 @@ void main() {
group( group(
'[Pickers tests]', '[Pickers tests]',
() { () {
group('Select film', () { setUpAll(() {
testWidgets( setupLightSensorStreamHandler();
'with the same ISO', setLightSensorAvilability(hasSensor: true);
(tester) async {
await tester.pumpApplication();
await tester.takePhoto();
// Verify that reciprocity failure is applies for the film is not selected
expectAnimatedPickerWith<FilmPicker>(title: S.current.film, value: S.current.none);
expectExposurePairsContainer('$mockPhotoFastestExposurePair', '$mockPhotoSlowestExposurePair');
expectMeasureButton(mockPhotoEv100);
await tester.openAnimatedPicker<FilmPicker>();
await tester.tapDescendantTextOf<DialogPicker<Film>>(mockFilms.first.name);
await tester.tapSelectButton();
/// Verify that exposure pairs are the same, except that the reciprocity failure is applied
expectExposurePairsContainer(
'$mockPhotoFastestExposurePair',
'$mockPhotoSlowestAperture - ${mockFilms.first.reciprocityFailure(mockPhotoSlowestShutterSpeed)}',
);
expectMeasureButton(mockPhotoEv100);
/// Make sure, that the EV is not changed
await tester.takePhoto();
expectExposurePairsContainer(
'$mockPhotoFastestExposurePair',
'$mockPhotoSlowestAperture - ${mockFilms.first.reciprocityFailure(mockPhotoSlowestShutterSpeed)}',
);
expectMeasureButton(mockPhotoEv100);
},
);
testWidgets(
'with greater ISO',
(tester) async {
await tester.pumpApplication();
await tester.takePhoto();
// Verify that reciprocity failure is applies for the film is not selected
expectAnimatedPickerWith<FilmPicker>(title: S.current.film, value: S.current.none);
expectExposurePairsContainer('$mockPhotoFastestExposurePair', '$mockPhotoSlowestExposurePair');
expectMeasureButton(mockPhotoEv100);
await tester.openAnimatedPicker<FilmPicker>();
await tester.tapDescendantTextOf<DialogPicker<Film>>(mockFilms[1].name);
await tester.tapSelectButton();
/// Verify that exposure pairs are the same, except that the reciprocity failure is applied
expectExposurePairsContainer(
'$mockPhotoFastestExposurePair',
'$mockPhotoSlowestAperture - ${mockFilms[1].reciprocityFailure(mockPhotoSlowestShutterSpeed)}',
);
expectMeasureButton(mockPhotoEv100);
/// Make sure, that the EV is not changed
await tester.takePhoto();
expectExposurePairsContainer(
'$mockPhotoFastestExposurePair',
'$mockPhotoSlowestAperture - ${mockFilms[1].reciprocityFailure(mockPhotoSlowestShutterSpeed)}',
);
expectMeasureButton(mockPhotoEv100);
},
);
}); });
testWidgets( tearDownAll(() {
'Select ISO +1 EV', resetLightSensorAvilability();
(tester) async { resetLightSensorStreamHandler();
await tester.pumpApplication(productStatus: IAPProductStatus.purchased); });
expectExposurePairsContainer('f/1.0 - 1/320', 'f/45 - 13"');
expectMeasureButton(mockPhotoEv100);
await tester.openAnimatedPicker<IsoValuePicker>(); setUp(() {
expect(find.byType(DialogPicker<IsoValue>), findsOneWidget); SharedPreferences.setMockInitialValues({UserPreferencesService.evSourceTypeKey: EvSourceType.sensor.index});
await tester.tapRadioListTile<IsoValue>('800'); });
await tester.tapSelectButton();
expectExposurePairsContainer('f/1.0 - 1/320', 'f/45 - 6"');
expectMeasureButton(8.3);
/// Make sure, that current ISO is used in metering group(
await tester.tap(find.byType(MeteringMeasureButton)); 'Select film',
await tester.tap(find.byType(MeteringMeasureButton)); () {
await tester.pumpAndSettle(); testMeteringPicker<FilmPicker, Film>(
expectExposurePairsContainer('f/1.0 - 1/320', 'f/45 - 6"'); 'with the same ISO',
expectMeasureButton(8.3); expectBefore: MeteringValuesExpectation(
mockPhotoFastestExposurePair.toString(),
mockPhotoSlowestExposurePair.toString(),
mockPhotoEv100,
),
valueToSelect: mockFilms[0].name,
expectAfter: MeteringValuesExpectation(
mockPhotoFastestExposurePair.toString(),
'$mockPhotoSlowestAperture - ${mockFilms[0].reciprocityFailure(mockPhotoSlowestShutterSpeed)}',
mockPhotoEv100,
),
);
testMeteringPicker<FilmPicker, Film>(
'with greater ISO',
expectBefore: MeteringValuesExpectation(
mockPhotoFastestExposurePair.toString(),
mockPhotoSlowestExposurePair.toString(),
mockPhotoEv100,
),
valueToSelect: mockFilms[1].name,
expectAfter: MeteringValuesExpectation(
mockPhotoFastestExposurePair.toString(),
'$mockPhotoSlowestAperture - ${mockFilms[1].reciprocityFailure(mockPhotoSlowestShutterSpeed)}',
mockPhotoEv100,
),
);
}, },
skip: true,
); );
testWidgets( testMeteringPicker<IsoValuePicker, IsoValue>(
'Select ISO +1 EV',
expectBefore: MeteringValuesExpectation(
mockPhotoFastestExposurePair.toString(),
mockPhotoSlowestExposurePair.toString(),
mockPhotoEv100,
),
valueToSelect: '400',
expectAfter: MeteringValuesExpectation(
'$mockPhotoFastestAperture - 1/1250',
'$mockPhotoSlowestAperture - 1.6"',
mockPhotoEv100 + 2,
),
);
testMeteringPicker<NdValuePicker, NdValue>(
'Select ND -1 EV', 'Select ND -1 EV',
(tester) async { expectBefore: MeteringValuesExpectation(
await tester.pumpApplication(productStatus: IAPProductStatus.purchased); mockPhotoFastestExposurePair.toString(),
expectExposurePairsContainer('f/1.0 - 1/320', 'f/45 - 13"'); mockPhotoSlowestExposurePair.toString(),
expectMeasureButton(mockPhotoEv100); mockPhotoEv100,
),
await tester.openAnimatedPicker<NdValuePicker>(); valueToSelect: '2',
expect(find.byType(DialogPicker<NdValue>), findsOneWidget); expectAfter: MeteringValuesExpectation(
await tester.tapRadioListTile<NdValue>('2'); '$mockPhotoFastestAperture - 1/160',
await tester.tapSelectButton(); '$mockPhotoSlowestAperture - 13"',
expectExposurePairsContainer('f/1.0 - 1/80', 'f/36 - 16"'); mockPhotoEv100 - 1,
expectMeasureButton(6.3); ),
/// Make sure, that current ISO is used in metering
await tester.tap(find.byType(MeteringMeasureButton));
await tester.tap(find.byType(MeteringMeasureButton));
await tester.pumpAndSettle();
expectExposurePairsContainer('f/1.0 - 1/80', 'f/36 - 16"');
expectMeasureButton(6.3);
},
skip: true,
); );
}, },
); );

View file

@ -0,0 +1,60 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:lightmeter/screens/metering/components/shared/readings_container/components/shared/animated_dialog_picker/components/dialog_picker/widget_picker_dialog.dart';
import 'package:meta/meta.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'expectations.dart';
import 'widget_tester_actions.dart';
class MeteringValuesExpectation {
final String fastestExposurePair;
final String slowestExposurePair;
final double ev;
const MeteringValuesExpectation(
this.fastestExposurePair,
this.slowestExposurePair,
this.ev,
);
}
/// Runs the picker test
///
/// 1. Takes photo and verifies `expectBefore` values
/// 2. Opens a picker and select the provided value
/// 3. Verifies `expectAfter`
/// 4. Takes photo and verifies `expectAfter` values
@isTest
void testMeteringPicker<P, V>(
String description, {
required MeteringValuesExpectation expectBefore,
required String valueToSelect,
required MeteringValuesExpectation expectAfter,
bool? skip,
}) {
testWidgets(
description,
(tester) async {
await tester.pumpApplication();
await tester.toggleIncidentMetering(expectBefore.ev);
// Verify that reciprocity failure is applies for the film is not selected
expectExposurePairsContainer(expectBefore.fastestExposurePair, expectBefore.slowestExposurePair);
expectMeasureButton(expectBefore.ev);
await tester.openAnimatedPicker<P>();
await tester.tapDescendantTextOf<DialogPicker<V>>(valueToSelect);
await tester.tapSelectButton();
/// Verify that exposure pairs are the same, except that the reciprocity failure is applied
expectExposurePairsContainer(expectAfter.fastestExposurePair, expectAfter.slowestExposurePair);
expectMeasureButton(expectAfter.ev);
/// Make sure, that the EV is not changed
await tester.toggleIncidentMetering(expectBefore.ev);
expectExposurePairsContainer(expectAfter.fastestExposurePair, expectAfter.slowestExposurePair);
expectMeasureButton(expectAfter.ev);
},
skip: skip,
);
}

View file

@ -3,22 +3,6 @@ import 'dart:math';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
Future<void> sendMockLux([int lux = 100]) async {
await TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
"light.eventChannel",
const StandardMethodCodec().encodeSuccessEnvelope(lux),
(ByteData? data) {},
);
}
Future<void> sendMockIncidentEv(double ev) async {
await TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
"light.eventChannel",
const StandardMethodCodec().encodeSuccessEnvelope((2.5 * pow(2, ev)).toInt()),
(ByteData? data) {},
);
}
void setLightSensorAvilability({required bool hasSensor}) { void setLightSensorAvilability({required bool hasSensor}) {
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler( TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler(
const MethodChannel('system_feature'), const MethodChannel('system_feature'),
@ -32,3 +16,43 @@ void setLightSensorAvilability({required bool hasSensor}) {
}, },
); );
} }
void resetLightSensorAvilability() {
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler(
const MethodChannel('system_feature'),
null,
);
}
Future<void> sendMockIncidentEv(double ev) => sendMockLux((2.5 * pow(2, ev)).toInt());
Future<void> sendMockLux([int lux = 100]) async {
await TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
"light.eventChannel",
const StandardMethodCodec().encodeSuccessEnvelope(lux),
(ByteData? data) {},
);
}
void setupLightSensorStreamHandler() {
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler(
const MethodChannel('light.eventChannel'),
(methodCall) async {
switch (methodCall.method) {
case "listen":
return;
case "cancel":
return;
default:
return null;
}
},
);
}
void resetLightSensorStreamHandler() {
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler(
const MethodChannel('light.eventChannel'),
null,
);
}