MeasureEvent tests revision

This commit is contained in:
Vadim 2023-06-08 11:59:21 +02:00
parent 5ae6dc19b9
commit c7d30510f0
3 changed files with 63 additions and 138 deletions

View file

@ -41,9 +41,6 @@ class MeteringBloc extends Bloc<MeteringEvent, MeteringState> {
@visibleForTesting @visibleForTesting
double? ev100; double? ev100;
@visibleForTesting
bool isMeteringInProgress = false;
MeteringBloc( MeteringBloc(
this._communicationBloc, this._communicationBloc,
this._meteringInteractor, this._meteringInteractor,
@ -83,8 +80,10 @@ class MeteringBloc extends Bloc<MeteringEvent, MeteringState> {
@visibleForTesting @visibleForTesting
void onCommunicationState(communication_states.ScreenState communicationState) { void onCommunicationState(communication_states.ScreenState communicationState) {
if (communicationState is communication_states.MeasuredState) { if (communicationState is communication_states.MeasuredState) {
isMeteringInProgress = communicationState is communication_states.MeteringInProgressState; _handleEv100(
handleEv100(communicationState.ev100); communicationState.ev100,
continuousMetering: communicationState is communication_states.MeteringInProgressState,
);
} }
} }
@ -174,14 +173,13 @@ class MeteringBloc extends Bloc<MeteringEvent, MeteringState> {
); );
} }
void _updateMeasurements() => handleEv100(ev100); void _updateMeasurements() => _handleEv100(ev100, continuousMetering: false);
@visibleForTesting void _handleEv100(double? ev100, {required bool continuousMetering}) {
void handleEv100(double? ev100) {
if (ev100 == null || ev100.isNaN || ev100.isInfinite) { if (ev100 == null || ev100.isNaN || ev100.isInfinite) {
add(const MeasureErrorEvent()); add(MeasureErrorEvent(continuousMetering: continuousMetering));
} else { } else {
add(MeasuredEvent(ev100)); add(MeasuredEvent(ev100, continuousMetering: continuousMetering));
} }
} }
@ -196,12 +194,12 @@ class MeteringBloc extends Bloc<MeteringEvent, MeteringState> {
iso: iso, iso: iso,
nd: nd, nd: nd,
exposurePairs: buildExposureValues(ev), exposurePairs: buildExposureValues(ev),
continuousMetering: isMeteringInProgress, continuousMetering: event.continuousMetering,
), ),
); );
} }
void _onMeasureError(MeasureErrorEvent _, Emitter emit) { void _onMeasureError(MeasureErrorEvent event, Emitter emit) {
_meteringInteractor.errorVibration(); _meteringInteractor.errorVibration();
ev100 = null; ev100 = null;
emit( emit(
@ -211,7 +209,7 @@ class MeteringBloc extends Bloc<MeteringEvent, MeteringState> {
iso: iso, iso: iso,
nd: nd, nd: nd,
exposurePairs: const [], exposurePairs: const [],
continuousMetering: isMeteringInProgress, continuousMetering: event.continuousMetering,
), ),
); );
} }

View file

@ -41,10 +41,13 @@ class MeasureEvent extends MeteringEvent {
class MeasuredEvent extends MeteringEvent { class MeasuredEvent extends MeteringEvent {
final double ev100; final double ev100;
final bool continuousMetering;
const MeasuredEvent(this.ev100); const MeasuredEvent(this.ev100, {required this.continuousMetering});
} }
class MeasureErrorEvent extends MeteringEvent { class MeasureErrorEvent extends MeteringEvent {
const MeasureErrorEvent(); final bool continuousMetering;
const MeasureErrorEvent({required this.continuousMetering});
} }

View file

@ -1,7 +1,6 @@
import 'package:bloc_test/bloc_test.dart'; import 'package:bloc_test/bloc_test.dart';
import 'package:lightmeter/data/models/film.dart'; import 'package:lightmeter/data/models/film.dart';
import 'package:lightmeter/interactors/metering_interactor.dart'; import 'package:lightmeter/interactors/metering_interactor.dart';
import 'package:lightmeter/res/dimens.dart';
import 'package:lightmeter/screens/metering/bloc_metering.dart'; import 'package:lightmeter/screens/metering/bloc_metering.dart';
import 'package:lightmeter/screens/metering/communication/bloc_communication_metering.dart'; import 'package:lightmeter/screens/metering/communication/bloc_communication_metering.dart';
import 'package:lightmeter/screens/metering/communication/event_communication_metering.dart' import 'package:lightmeter/screens/metering/communication/event_communication_metering.dart'
@ -26,7 +25,6 @@ void main() {
late EquipmentProfileData equipmentProfileData; late EquipmentProfileData equipmentProfileData;
late MeteringBloc bloc; late MeteringBloc bloc;
const iso100 = IsoValue(100, StopType.full); const iso100 = IsoValue(100, StopType.full);
double initEV = 0.0;
setUpAll(() { setUpAll(() {
communicationBloc = _MockMeteringCommunicationBloc(); communicationBloc = _MockMeteringCommunicationBloc();
@ -45,6 +43,7 @@ void main() {
when<Film>(() => meteringInteractor.film).thenReturn(Film.values.first); when<Film>(() => meteringInteractor.film).thenReturn(Film.values.first);
when(meteringInteractor.quickVibration).thenAnswer((_) async {}); when(meteringInteractor.quickVibration).thenAnswer((_) async {});
when(meteringInteractor.responseVibration).thenAnswer((_) async {}); when(meteringInteractor.responseVibration).thenAnswer((_) async {});
when(meteringInteractor.errorVibration).thenAnswer((_) async {});
}); });
setUp(() { setUp(() {
@ -69,74 +68,14 @@ void main() {
.having((state) => state.film, 'film', bloc.film) .having((state) => state.film, 'film', bloc.film)
.having((state) => state.iso, 'iso', bloc.iso) .having((state) => state.iso, 'iso', bloc.iso)
.having((state) => state.nd, 'nd', bloc.nd) .having((state) => state.nd, 'nd', bloc.nd)
.having((state) => state.exposurePairs, 'exposurePairs', const []).having( .having((state) => state.exposurePairs, 'exposurePairs', const []),
(state) => state.continuousMetering,
'continuousMetering',
bloc.isMeteringInProgress,
),
); );
}); });
blocTest<MeteringBloc, MeteringState>(
'Measured',
build: () => bloc,
act: (bloc) => bloc.add(const MeasuredEvent(2)),
verify: (_) {
verify(() => meteringInteractor.responseVibration()).called(1);
},
expect: () => [
isA<MeteringDataState>()
.having((_) => bloc.ev100, 'ev100', 2)
.having((state) => state.ev, 'ev', 2)
.having((state) => state.film, 'film', Film.values.first)
.having((state) => state.iso, 'iso', iso100)
.having((state) => state.nd, 'nd', NdValue.values.first),
],
);
blocTest<MeteringBloc, MeteringState>(
'Measured',
build: () => bloc,
setUp: () {
when<IsoValue>(() => meteringInteractor.iso).thenReturn(iso100);
},
act: (bloc) {
bloc.add(const MeasuredEvent(3));
bloc.add(const MeasuredEvent(7));
bloc.add(const MeasuredEvent(2));
},
verify: (_) {
//verify(() => meteringInteractor.responseVibration()).called(1);
},
expect: () => [
isA<MeteringDataState>()
.having((_) => bloc.ev100, 'ev100', 3)
.having((_) => bloc.iso, 'blocIso', iso100)
.having((state) => state.ev, 'ev', 4)
.having((state) => state.film, 'film', Film.values.first)
.having((state) => state.iso, 'iso', iso100)
.having((state) => state.nd, 'nd', NdValue.values.first),
isA<MeteringDataState>()
.having((_) => bloc.ev100, 'ev100', 7)
.having((_) => bloc.iso, 'blocIso', iso100)
.having((state) => state.ev, 'ev', 8)
.having((state) => state.film, 'film', Film.values.first)
.having((state) => state.iso, 'iso', iso100)
.having((state) => state.nd, 'nd', NdValue.values.first),
isA<MeteringDataState>()
.having((_) => bloc.ev100, 'ev100', 2)
.having((_) => bloc.iso, 'blocIso', iso100)
.having((state) => state.ev, 'ev', 3)
.having((state) => state.film, 'film', Film.values.first)
.having((state) => state.iso, 'iso', iso100)
.having((state) => state.nd, 'nd', NdValue.values.first),
],
);
}); });
group('`MeasureEvent` tests', () { group('`MeasureEvent` tests', () {
blocTest<MeteringBloc, MeteringState>( blocTest<MeteringBloc, MeteringState>(
'`MeasureEvent` -> `MeteringEndedState`', '`MeasureEvent` -> success',
build: () => bloc, build: () => bloc,
act: (bloc) async { act: (bloc) async {
bloc.add(const MeasureEvent()); bloc.add(const MeasureEvent());
@ -148,93 +87,78 @@ void main() {
verify(() => meteringInteractor.responseVibration()).called(1); verify(() => meteringInteractor.responseVibration()).called(1);
}, },
expect: () => [ expect: () => [
isA<LoadingState>() isA<LoadingState>(),
.having((state) => state.film, 'film', Film.values.first)
.having((state) => state.iso, 'iso', iso100)
.having((state) => state.nd, 'nd', NdValue.values.first),
isA<MeteringDataState>() isA<MeteringDataState>()
.having((_) => bloc.isMeteringInProgress, 'isMeteringInProgress', false) .having((state) => state.continuousMetering, 'continuousMetering', false)
.having((_) => bloc.ev100, 'ev100', 2) .having((state) => state.ev, 'ev', 2),
.having((state) => state.ev, 'ev', 2)
.having((state) => state.film, 'film', Film.values.first)
.having((state) => state.iso, 'iso', iso100)
.having((state) => state.nd, 'nd', NdValue.values.first),
], ],
); );
blocTest<MeteringBloc, MeteringState>( blocTest<MeteringBloc, MeteringState>(
'`MeasureEvent` -> `MeteringInProgressState`', '`MeasureEvent` -> error',
build: () => bloc, build: () => bloc,
act: (bloc) async { act: (bloc) async {
bloc.add(const MeasureEvent()); bloc.add(const MeasureEvent());
bloc.onCommunicationState(const communication_states.MeteringInProgressState(2)); bloc.onCommunicationState(const communication_states.MeteringEndedState(null));
}, },
verify: (_) { verify: (_) {
verify(() => meteringInteractor.quickVibration()).called(1); verify(() => meteringInteractor.quickVibration()).called(1);
verify(() => communicationBloc.add(const communication_events.MeasureEvent())).called(1); verify(() => communicationBloc.add(const communication_events.MeasureEvent())).called(1);
verify(() => meteringInteractor.responseVibration()).called(1); verify(() => meteringInteractor.errorVibration()).called(1);
}, },
expect: () => [ expect: () => [
isA<LoadingState>() isA<LoadingState>(),
.having((state) => state.film, 'film', Film.values.first)
.having((state) => state.iso, 'iso', iso100)
.having((state) => state.nd, 'nd', NdValue.values.first),
isA<MeteringDataState>() isA<MeteringDataState>()
.having((_) => bloc.isMeteringInProgress, 'isMeteringInProgress', true) .having((state) => state.continuousMetering, 'continuousMetering', false)
.having((_) => bloc.ev100, 'ev100', 2) .having((_) => bloc.ev100, 'ev100', null)
.having((state) => state.ev, 'ev', 2) .having((state) => state.ev, 'ev', null),
.having((state) => state.film, 'film', Film.values.first)
.having((state) => state.iso, 'iso', iso100)
.having((state) => state.nd, 'nd', NdValue.values.first),
], ],
); );
});
group('MeteringBloc `IsoChangedEvent` tests:', () {
const isoValueToSet = IsoValue(200, StopType.full);
blocTest<MeteringBloc, MeteringState>( blocTest<MeteringBloc, MeteringState>(
'ISO change', '`MeasureEvent` -> continuous metering',
setUp: () {
when<void>(() => meteringInteractor.iso = isoValueToSet);
},
build: () => bloc, build: () => bloc,
act: (bloc) async { act: (bloc) async {
bloc.add(const MeasuredEvent(1)); // delays here simulate light sensor behaviour
bloc.add(const IsoChangedEvent(isoValueToSet)); // when sensor does not fire new LUX events when value is not changed
await Future.delayed(Dimens.durationS);
bloc.add(const MeasureEvent()); bloc.add(const MeasureEvent());
await Future.delayed(Dimens.durationS); bloc.onCommunicationState(const communication_states.MeteringInProgressState(null));
bloc.add(const MeasuredEvent(3)); await Future.delayed(const Duration(seconds: 1));
await Future.delayed(Dimens.durationS); bloc.onCommunicationState(const communication_states.MeteringInProgressState(2));
bloc.onCommunicationState(const communication_states.MeteringInProgressState(5.5));
await Future.delayed(const Duration(seconds: 2));
bloc.onCommunicationState(const communication_states.MeteringInProgressState(null));
bloc.onCommunicationState(const communication_states.MeteringInProgressState(4));
bloc.add(const MeasureEvent());
bloc.onCommunicationState(const communication_states.MeteringEndedState(4));
}, },
verify: (_) { verify: (_) {
verify(() => meteringInteractor.iso = isoValueToSet).called(1); verify(() => meteringInteractor.quickVibration()).called(2);
verify(() => communicationBloc.add(const communication_events.MeasureEvent())).called(2);
verify(() => meteringInteractor.responseVibration()).called(4);
verify(() => meteringInteractor.errorVibration()).called(2);
}, },
expect: () => [ expect: () => [
isA<LoadingState>(),
isA<MeteringDataState>() isA<MeteringDataState>()
.having((_) => bloc.ev100, 'ev100', 1) .having((state) => state.continuousMetering, 'continuousMetering', true)
.having((state) => state.ev, 'ev', 1) .having((state) => state.ev, 'ev', null),
.having((state) => state.film, 'film', Film.values.first)
.having((state) => state.iso, 'iso', iso100)
.having((state) => state.nd, 'nd', NdValue.values.first),
isA<MeteringDataState>() isA<MeteringDataState>()
.having((_) => bloc.ev100, 'ev100', 1) .having((state) => state.continuousMetering, 'continuousMetering', true)
.having((_) => bloc.iso, 'blocIso', isoValueToSet) .having((state) => state.ev, 'ev', 2),
.having((state) => state.ev, 'ev', 2)
.having((state) => state.film, 'film', Film.values.first)
.having((state) => state.iso, 'iso', isoValueToSet)
.having((state) => state.nd, 'nd', NdValue.values.first),
isA<LoadingState>()
.having((state) => state.film, 'film', Film.values.first)
.having((state) => state.iso, 'iso', isoValueToSet)
.having((state) => state.nd, 'nd', NdValue.values.first),
isA<MeteringDataState>() isA<MeteringDataState>()
//.having((_) => bloc.ev100, 'ev100', 3) .having((state) => state.continuousMetering, 'continuousMetering', true)
.having((_) => bloc.iso, 'blocIso', isoValueToSet) .having((state) => state.ev, 'ev', 5.5),
//.having((state) => state.ev, 'ev', 4) isA<MeteringDataState>()
.having((state) => state.film, 'film', Film.values.first) .having((state) => state.continuousMetering, 'continuousMetering', true)
.having((state) => state.iso, 'iso', isoValueToSet) .having((state) => state.ev, 'ev', null),
.having((state) => state.nd, 'nd', NdValue.values.first), isA<MeteringDataState>()
.having((state) => state.continuousMetering, 'continuousMetering', true)
.having((state) => state.ev, 'ev', 4),
isA<LoadingState>(),
isA<MeteringDataState>()
.having((state) => state.continuousMetering, 'continuousMetering', false)
.having((state) => state.ev, 'ev', 4),
], ],
); );
}); });