mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2024-11-25 17:00:39 +00:00
fixed light sensor platform mocks
This commit is contained in:
parent
24804a119e
commit
043439b71f
3 changed files with 179 additions and 123 deletions
|
@ -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,
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
60
integration_test/utils/metering_picker_test.dart
Normal file
60
integration_test/utils/metering_picker_test.dart
Normal 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,
|
||||||
|
);
|
||||||
|
}
|
|
@ -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,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue