mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2025-02-21 03:50:40 +00:00
wip
This commit is contained in:
parent
2eb94f8a09
commit
737daad6d0
5 changed files with 237 additions and 5 deletions
|
@ -53,8 +53,6 @@ class CameraContainerBloc extends EvSourceBlocBase<CameraContainerEvent, CameraC
|
|||
on<ZoomChangedEvent>(_onZoomChanged);
|
||||
on<ExposureOffsetChangedEvent>(_onExposureOffsetChanged);
|
||||
on<ExposureOffsetResetEvent>(_onExposureOffsetResetEvent);
|
||||
|
||||
add(const RequestPermissionEvent());
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -5,6 +5,7 @@ import 'package:lightmeter/data/models/film.dart';
|
|||
import 'package:lightmeter/interactors/metering_interactor.dart';
|
||||
import 'package:lightmeter/screens/metering/communication/bloc_communication_metering.dart';
|
||||
import 'package:lightmeter/screens/metering/components/camera_container/bloc_container_camera.dart';
|
||||
import 'package:lightmeter/screens/metering/components/camera_container/event_container_camera.dart';
|
||||
import 'package:lightmeter/screens/metering/components/camera_container/widget_container_camera.dart';
|
||||
import 'package:lightmeter/utils/inherited_generics.dart';
|
||||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||
|
@ -40,7 +41,7 @@ class CameraContainerProvider extends StatelessWidget {
|
|||
create: (context) => CameraContainerBloc(
|
||||
context.get<MeteringInteractor>(),
|
||||
context.read<MeteringCommunicationBloc>(),
|
||||
),
|
||||
)..add(const RequestPermissionEvent()),
|
||||
child: CameraContainer(
|
||||
fastest: fastest,
|
||||
slowest: slowest,
|
||||
|
|
|
@ -40,6 +40,8 @@ dev_dependencies:
|
|||
build_runner: ^2.1.7
|
||||
flutter_launcher_icons: 0.11.0
|
||||
flutter_native_splash: 2.2.16
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
google_fonts: 3.0.1
|
||||
lint: 2.1.2
|
||||
mocktail: 0.3.0
|
||||
|
|
|
@ -0,0 +1,231 @@
|
|||
import 'package:bloc_test/bloc_test.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:lightmeter/interactors/metering_interactor.dart';
|
||||
import 'package:lightmeter/screens/metering/communication/bloc_communication_metering.dart';
|
||||
import 'package:lightmeter/screens/metering/communication/event_communication_metering.dart'
|
||||
as communication_events;
|
||||
import 'package:lightmeter/screens/metering/communication/state_communication_metering.dart'
|
||||
as communication_states;
|
||||
import 'package:lightmeter/screens/metering/components/camera_container/bloc_container_camera.dart';
|
||||
import 'package:lightmeter/screens/metering/components/camera_container/event_container_camera.dart';
|
||||
import 'package:lightmeter/screens/metering/components/camera_container/models/camera_error_type.dart';
|
||||
import 'package:lightmeter/screens/metering/components/camera_container/state_container_camera.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
|
||||
class _MockMeteringCommunicationBloc extends MockBloc<
|
||||
communication_events.MeteringCommunicationEvent,
|
||||
communication_states.MeteringCommunicationState> implements MeteringCommunicationBloc {}
|
||||
|
||||
class _MockMeteringInteractor extends Mock implements MeteringInteractor {}
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
late _MockMeteringInteractor meteringInteractor;
|
||||
late _MockMeteringCommunicationBloc communicationBloc;
|
||||
late CameraContainerBloc bloc;
|
||||
|
||||
setUpAll(() {
|
||||
meteringInteractor = _MockMeteringInteractor();
|
||||
communicationBloc = _MockMeteringCommunicationBloc();
|
||||
});
|
||||
|
||||
setUp(() {
|
||||
bloc = CameraContainerBloc(
|
||||
meteringInteractor,
|
||||
communicationBloc,
|
||||
);
|
||||
});
|
||||
|
||||
tearDown(() {
|
||||
bloc.close();
|
||||
});
|
||||
|
||||
group(
|
||||
'`RequestPermissionEvent` tests',
|
||||
() {
|
||||
blocTest<CameraContainerBloc, CameraContainerState>(
|
||||
'Request denied',
|
||||
build: () => bloc,
|
||||
setUp: () {
|
||||
when(() => meteringInteractor.requestPermission()).thenAnswer((_) async => false);
|
||||
},
|
||||
act: (bloc) => bloc.add(const RequestPermissionEvent()),
|
||||
verify: (_) {
|
||||
verify(() => meteringInteractor.requestPermission()).called(1);
|
||||
},
|
||||
expect: () => [
|
||||
isA<CameraErrorState>()
|
||||
.having((state) => state.error, "error", CameraErrorType.permissionNotGranted),
|
||||
],
|
||||
);
|
||||
|
||||
blocTest<CameraContainerBloc, CameraContainerState>(
|
||||
'Request granted -> check denied',
|
||||
build: () => bloc,
|
||||
setUp: () {
|
||||
when(() => meteringInteractor.requestPermission()).thenAnswer((_) async => true);
|
||||
when(() => meteringInteractor.checkCameraPermission()).thenAnswer((_) async => false);
|
||||
},
|
||||
act: (bloc) => bloc.add(const RequestPermissionEvent()),
|
||||
verify: (_) {
|
||||
verify(() => meteringInteractor.requestPermission()).called(1);
|
||||
verify(() => meteringInteractor.checkCameraPermission()).called(1);
|
||||
},
|
||||
expect: () => [
|
||||
isA<CameraLoadingState>(),
|
||||
isA<CameraErrorState>()
|
||||
.having((state) => state.error, "error", CameraErrorType.permissionNotGranted),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
group(
|
||||
'`InitializeEvent` tests',
|
||||
() {
|
||||
const cameraMethodChannel = MethodChannel('plugins.flutter.io/camera');
|
||||
const cameraIdMethodChannel = MethodChannel('flutter.io/cameraPlugin/camera1');
|
||||
const availableCameras = [
|
||||
{
|
||||
"name": "front",
|
||||
"lensFacing": "front",
|
||||
"sensorOrientation": 0,
|
||||
},
|
||||
{
|
||||
"name": "back",
|
||||
"lensFacing": "back",
|
||||
"sensorOrientation": 0,
|
||||
},
|
||||
];
|
||||
|
||||
blocTest<CameraContainerBloc, CameraContainerState>(
|
||||
'No cameras detected',
|
||||
setUp: () {
|
||||
when(() => meteringInteractor.checkCameraPermission()).thenAnswer((_) async => true);
|
||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
||||
.setMockMethodCallHandler(
|
||||
cameraMethodChannel,
|
||||
(methodCall) async {
|
||||
switch (methodCall.method) {
|
||||
case "availableCameras":
|
||||
return const [];
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
tearDown: () {
|
||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
||||
.setMockMethodCallHandler(cameraMethodChannel, null);
|
||||
},
|
||||
build: () => bloc,
|
||||
act: (bloc) => bloc.add(const InitializeEvent()),
|
||||
verify: (_) {
|
||||
verify(() => meteringInteractor.checkCameraPermission()).called(1);
|
||||
},
|
||||
expect: () => [
|
||||
isA<CameraLoadingState>(),
|
||||
isA<CameraErrorState>()
|
||||
.having((state) => state.error, "error", CameraErrorType.noCamerasDetected),
|
||||
],
|
||||
);
|
||||
|
||||
blocTest<CameraContainerBloc, CameraContainerState>(
|
||||
'Catch other initialization errors',
|
||||
setUp: () {
|
||||
when(() => meteringInteractor.checkCameraPermission()).thenAnswer((_) async => true);
|
||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
||||
.setMockMethodCallHandler(
|
||||
cameraMethodChannel,
|
||||
(methodCall) async {
|
||||
switch (methodCall.method) {
|
||||
case "availableCameras":
|
||||
return availableCameras;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
tearDown: () {
|
||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
||||
.setMockMethodCallHandler(cameraMethodChannel, null);
|
||||
},
|
||||
build: () => bloc,
|
||||
act: (bloc) => bloc.add(const InitializeEvent()),
|
||||
verify: (_) {
|
||||
verify(() => meteringInteractor.checkCameraPermission()).called(1);
|
||||
},
|
||||
expect: () => [
|
||||
isA<CameraLoadingState>(),
|
||||
isA<CameraErrorState>().having((state) => state.error, "error", CameraErrorType.other),
|
||||
],
|
||||
);
|
||||
|
||||
blocTest<CameraContainerBloc, CameraContainerState>(
|
||||
'Successful initialization',
|
||||
setUp: () {
|
||||
when(() => meteringInteractor.checkCameraPermission()).thenAnswer((_) async => true);
|
||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
||||
.setMockMethodCallHandler(
|
||||
cameraMethodChannel,
|
||||
(methodCall) async {
|
||||
switch (methodCall.method) {
|
||||
case "availableCameras":
|
||||
return availableCameras;
|
||||
case "create":
|
||||
return {"cameraId": 1};
|
||||
case "initialize":
|
||||
await cameraIdMethodChannel.invokeMockMethod("initialized", {
|
||||
'cameraId': 1,
|
||||
'previewWidth': 2160.0,
|
||||
'previewHeight': 3840.0,
|
||||
'exposureMode': 'auto',
|
||||
'exposurePointSupported': true,
|
||||
'focusMode': 'auto',
|
||||
'focusPointSupported': true,
|
||||
});
|
||||
return {};
|
||||
case "setFlashMode":
|
||||
return '';
|
||||
// TODO: implement responses for other methods used initialization
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
tearDown: () {
|
||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
||||
.setMockMethodCallHandler(cameraMethodChannel, null);
|
||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
||||
.setMockMethodCallHandler(cameraIdMethodChannel, null);
|
||||
},
|
||||
build: () => bloc,
|
||||
act: (bloc) => bloc.add(const InitializeEvent()),
|
||||
verify: (_) {
|
||||
verify(() => meteringInteractor.checkCameraPermission()).called(1);
|
||||
},
|
||||
expect: () => [
|
||||
isA<CameraLoadingState>(),
|
||||
isA<CameraInitializedState>(),
|
||||
isA<CameraActiveState>(),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
extension _MethodChannelMock on MethodChannel {
|
||||
Future<void> invokeMockMethod(String method, dynamic arguments) async {
|
||||
final data = const StandardMethodCodec().encodeMethodCall(MethodCall(method, arguments));
|
||||
await TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
|
||||
name,
|
||||
data,
|
||||
(ByteData? data) {},
|
||||
);
|
||||
}
|
||||
}
|
|
@ -18,13 +18,13 @@ class _MockMeteringCommunicationBloc extends MockBloc<
|
|||
class _MockMeteringInteractor extends Mock implements MeteringInteractor {}
|
||||
|
||||
void main() {
|
||||
late _MockMeteringCommunicationBloc communicationBloc;
|
||||
late _MockMeteringInteractor meteringInteractor;
|
||||
late _MockMeteringCommunicationBloc communicationBloc;
|
||||
late LightSensorContainerBloc bloc;
|
||||
|
||||
setUpAll(() {
|
||||
communicationBloc = _MockMeteringCommunicationBloc();
|
||||
meteringInteractor = _MockMeteringInteractor();
|
||||
communicationBloc = _MockMeteringCommunicationBloc();
|
||||
});
|
||||
|
||||
setUp(() {
|
||||
|
|
Loading…
Reference in a new issue