mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2024-11-21 23:10:40 +00:00
Fixed & tested exposure pairs list builder
This commit is contained in:
parent
9ef7764b58
commit
df81e13a63
4 changed files with 714 additions and 18 deletions
|
@ -8,4 +8,16 @@ class ExposurePair {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => '$aperture - $shutterSpeed';
|
String toString() => '$aperture - $shutterSpeed';
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
if (other.runtimeType != runtimeType) return false;
|
||||||
|
return other is ExposurePair &&
|
||||||
|
other.aperture == aperture &&
|
||||||
|
other.shutterSpeed == shutterSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(aperture, shutterSpeed, runtimeType);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@ double log10polynomian(
|
||||||
) =>
|
) =>
|
||||||
a * pow(log10(x), 2) + b * log10(x) + c;
|
a * pow(log10(x), 2) + b * log10(x) + c;
|
||||||
|
|
||||||
|
typedef ReciprocityFailureBuilder = ShutterSpeedValue Function(ShutterSpeedValue shutterSpeed);
|
||||||
|
|
||||||
/// Only Ilford films have reciprocity formulas provided by the manufacturer:
|
/// Only Ilford films have reciprocity formulas provided by the manufacturer:
|
||||||
/// https://www.ilfordphoto.com/wp/wp-content/uploads/2017/06/Reciprocity-Failure-Compensation.pdf
|
/// https://www.ilfordphoto.com/wp/wp-content/uploads/2017/06/Reciprocity-Failure-Compensation.pdf
|
||||||
///
|
///
|
||||||
|
|
|
@ -30,7 +30,7 @@ class MeteringScreen extends StatelessWidget {
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: BlocBuilder<MeteringBloc, MeteringState>(
|
child: BlocBuilder<MeteringBloc, MeteringState>(
|
||||||
builder: (_, state) => _MeteringContainerBuidler(
|
builder: (_, state) => MeteringContainerBuidler(
|
||||||
ev: state is MeteringDataState ? state.ev : null,
|
ev: state is MeteringDataState ? state.ev : null,
|
||||||
film: state.film,
|
film: state.film,
|
||||||
iso: state.iso,
|
iso: state.iso,
|
||||||
|
@ -77,17 +77,18 @@ class _InheritedListeners extends StatelessWidget {
|
||||||
context.read<MeteringBloc>().add(EquipmentProfileChangedEvent(value));
|
context.read<MeteringBloc>().add(EquipmentProfileChangedEvent(value));
|
||||||
},
|
},
|
||||||
child: InheritedModelAspectListener<MeteringScreenLayoutFeature, bool>(
|
child: InheritedModelAspectListener<MeteringScreenLayoutFeature, bool>(
|
||||||
aspect: MeteringScreenLayoutFeature.equipmentProfiles,
|
aspect: MeteringScreenLayoutFeature.filmPicker,
|
||||||
onDidChangeDependencies: (value) {
|
onDidChangeDependencies: (value) {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
EquipmentProfileProvider.of(context).setProfile(context.get<EquipmentProfiles>().first);
|
context.read<MeteringBloc>().add(const FilmChangedEvent(Film.other()));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: InheritedModelAspectListener<MeteringScreenLayoutFeature, bool>(
|
child: InheritedModelAspectListener<MeteringScreenLayoutFeature, bool>(
|
||||||
aspect: MeteringScreenLayoutFeature.filmPicker,
|
aspect: MeteringScreenLayoutFeature.equipmentProfiles,
|
||||||
onDidChangeDependencies: (value) {
|
onDidChangeDependencies: (value) {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
context.read<MeteringBloc>().add(const FilmChangedEvent(Film.other()));
|
EquipmentProfileProvider.of(context)
|
||||||
|
.setProfile(context.get<EquipmentProfiles>().first);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: child,
|
child: child,
|
||||||
|
@ -97,7 +98,7 @@ class _InheritedListeners extends StatelessWidget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _MeteringContainerBuidler extends StatelessWidget {
|
class MeteringContainerBuidler extends StatelessWidget {
|
||||||
final double? ev;
|
final double? ev;
|
||||||
final Film film;
|
final Film film;
|
||||||
final IsoValue iso;
|
final IsoValue iso;
|
||||||
|
@ -106,7 +107,7 @@ class _MeteringContainerBuidler extends StatelessWidget {
|
||||||
final ValueChanged<IsoValue> onIsoChanged;
|
final ValueChanged<IsoValue> onIsoChanged;
|
||||||
final ValueChanged<NdValue> onNdChanged;
|
final ValueChanged<NdValue> onNdChanged;
|
||||||
|
|
||||||
const _MeteringContainerBuidler({
|
const MeteringContainerBuidler({
|
||||||
required this.ev,
|
required this.ev,
|
||||||
required this.film,
|
required this.film,
|
||||||
required this.iso,
|
required this.iso,
|
||||||
|
@ -118,7 +119,14 @@ class _MeteringContainerBuidler extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final exposurePairs = ev != null ? buildExposureValues(context, ev!, film) : <ExposurePair>[];
|
final exposurePairs = ev != null
|
||||||
|
? buildExposureValues(
|
||||||
|
ev!,
|
||||||
|
context.listen<StopType>(),
|
||||||
|
context.listen<EquipmentProfile>(),
|
||||||
|
film,
|
||||||
|
)
|
||||||
|
: <ExposurePair>[];
|
||||||
final fastest = exposurePairs.isNotEmpty ? exposurePairs.first : null;
|
final fastest = exposurePairs.isNotEmpty ? exposurePairs.first : null;
|
||||||
final slowest = exposurePairs.isNotEmpty ? exposurePairs.last : null;
|
final slowest = exposurePairs.isNotEmpty ? exposurePairs.last : null;
|
||||||
return context.listen<EvSourceType>() == EvSourceType.camera
|
return context.listen<EvSourceType>() == EvSourceType.camera
|
||||||
|
@ -146,28 +154,30 @@ class _MeteringContainerBuidler extends StatelessWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<ExposurePair> buildExposureValues(BuildContext context, double ev, Film film) {
|
@visibleForTesting
|
||||||
|
static List<ExposurePair> buildExposureValues(
|
||||||
|
double ev,
|
||||||
|
StopType stopType,
|
||||||
|
EquipmentProfile equipmentProfile,
|
||||||
|
Film film,
|
||||||
|
) {
|
||||||
if (ev.isNaN || ev.isInfinite) {
|
if (ev.isNaN || ev.isInfinite) {
|
||||||
return List.empty();
|
return List.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Depending on the `stopType` the exposure pairs list length is multiplied by 1,2 or 3
|
/// Depending on the `stopType` the exposure pairs list length is multiplied by 1,2 or 3
|
||||||
final StopType stopType = context.listen<StopType>();
|
|
||||||
final int evSteps = (ev * (stopType.index + 1)).round();
|
final int evSteps = (ev * (stopType.index + 1)).round();
|
||||||
|
|
||||||
final EquipmentProfile equipmentProfile = context.listen<EquipmentProfile>();
|
final apertureValues = ApertureValue.whereStopType(stopType);
|
||||||
final List<ApertureValue> apertureValues =
|
final shutterSpeedValues = ShutterSpeedValue.whereStopType(stopType);
|
||||||
equipmentProfile.apertureValues.whereStopType(stopType);
|
|
||||||
final List<ShutterSpeedValue> shutterSpeedValues =
|
|
||||||
equipmentProfile.shutterSpeedValues.whereStopType(stopType);
|
|
||||||
|
|
||||||
/// Basically we use 1" shutter speed as an anchor point for building the exposure pairs list.
|
/// Basically we use 1" shutter speed as an anchor point for building the exposure pairs list.
|
||||||
/// But user can exclude this value from the list using custom equipment profile.
|
/// But user can exclude this value from the list using custom equipment profile.
|
||||||
/// So we have to restore the index of the anchor value.
|
/// So we have to restore the index of the anchor value.
|
||||||
const ShutterSpeedValue anchorShutterSpeed = ShutterSpeedValue(1, false, StopType.full);
|
const anchorShutterSpeed = ShutterSpeedValue(1, false, StopType.full);
|
||||||
int anchorIndex = shutterSpeedValues.indexOf(anchorShutterSpeed);
|
int anchorIndex = shutterSpeedValues.indexOf(anchorShutterSpeed);
|
||||||
if (anchorIndex < 0) {
|
if (anchorIndex < 0) {
|
||||||
final filteredFullList = ShutterSpeedValue.values.whereStopType(stopType);
|
final filteredFullList = ShutterSpeedValue.whereStopType(stopType);
|
||||||
final customListStartIndex = filteredFullList.indexOf(shutterSpeedValues.first);
|
final customListStartIndex = filteredFullList.indexOf(shutterSpeedValues.first);
|
||||||
final fullListAnchor = filteredFullList.indexOf(anchorShutterSpeed);
|
final fullListAnchor = filteredFullList.indexOf(anchorShutterSpeed);
|
||||||
if (customListStartIndex < fullListAnchor) {
|
if (customListStartIndex < fullListAnchor) {
|
||||||
|
@ -200,7 +210,8 @@ class _MeteringContainerBuidler extends StatelessWidget {
|
||||||
if (itemsCount < 0) {
|
if (itemsCount < 0) {
|
||||||
return List.empty();
|
return List.empty();
|
||||||
}
|
}
|
||||||
return List.generate(
|
|
||||||
|
final exposurePairs = List.generate(
|
||||||
itemsCount,
|
itemsCount,
|
||||||
(index) => ExposurePair(
|
(index) => ExposurePair(
|
||||||
apertureValues[index + apertureOffset],
|
apertureValues[index + apertureOffset],
|
||||||
|
@ -208,5 +219,30 @@ class _MeteringContainerBuidler extends StatelessWidget {
|
||||||
),
|
),
|
||||||
growable: false,
|
growable: false,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// Full equipment profile, nothing to cut
|
||||||
|
if (equipmentProfile.id == "") {
|
||||||
|
return exposurePairs;
|
||||||
|
}
|
||||||
|
|
||||||
|
final equipmentApertureValues = equipmentProfile.apertureValues.whereStopType(stopType);
|
||||||
|
final equipmentShutterSpeedValues = equipmentProfile.shutterSpeedValues.whereStopType(stopType);
|
||||||
|
|
||||||
|
final startCutEV = max(
|
||||||
|
exposurePairs.first.aperture.difference(equipmentApertureValues.first),
|
||||||
|
exposurePairs.first.shutterSpeed.difference(equipmentShutterSpeedValues.first),
|
||||||
|
);
|
||||||
|
final endCutEV = max(
|
||||||
|
equipmentApertureValues.last.difference(exposurePairs.last.aperture),
|
||||||
|
equipmentShutterSpeedValues.last.difference(exposurePairs.last.shutterSpeed),
|
||||||
|
);
|
||||||
|
|
||||||
|
final startCut = (startCutEV * (stopType.index + 1)).round().clamp(0, itemsCount);
|
||||||
|
final endCut = (endCutEV * (stopType.index + 1)).round().clamp(0, itemsCount);
|
||||||
|
|
||||||
|
if (startCut > itemsCount - endCut) {
|
||||||
|
return const [];
|
||||||
|
}
|
||||||
|
return exposurePairs.sublist(startCut, itemsCount - endCut);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
646
test/screens/metering/screen_metering_test.dart
Normal file
646
test/screens/metering/screen_metering_test.dart
Normal file
|
@ -0,0 +1,646 @@
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:lightmeter/data/models/exposure_pair.dart';
|
||||||
|
import 'package:lightmeter/data/models/film.dart';
|
||||||
|
import 'package:lightmeter/screens/metering/screen_metering.dart';
|
||||||
|
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
const defaultEquipmentProfile = EquipmentProfileData(
|
||||||
|
id: "",
|
||||||
|
name: 'Default',
|
||||||
|
apertureValues: ApertureValue.values,
|
||||||
|
ndValues: NdValue.values,
|
||||||
|
shutterSpeedValues: ShutterSpeedValue.values,
|
||||||
|
isoValues: IsoValue.values,
|
||||||
|
);
|
||||||
|
|
||||||
|
group('Empty list', () {
|
||||||
|
List<ExposurePair> exposurePairsFull(double ev) => MeteringContainerBuidler.buildExposureValues(
|
||||||
|
ev,
|
||||||
|
StopType.full,
|
||||||
|
defaultEquipmentProfile,
|
||||||
|
const Film.other(),
|
||||||
|
);
|
||||||
|
|
||||||
|
test('isNan', () {
|
||||||
|
expect(exposurePairsFull(double.nan), const []);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('isInifinity', () {
|
||||||
|
expect(exposurePairsFull(double.infinity), const []);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
group('Default equipment profile', () {
|
||||||
|
group("StopType.full", () {
|
||||||
|
List<ExposurePair> exposurePairsFull(double ev) =>
|
||||||
|
MeteringContainerBuidler.buildExposureValues(
|
||||||
|
ev,
|
||||||
|
StopType.full,
|
||||||
|
defaultEquipmentProfile,
|
||||||
|
const Film.other(),
|
||||||
|
);
|
||||||
|
|
||||||
|
test('EV 1', () {
|
||||||
|
final exposurePairs = exposurePairsFull(1);
|
||||||
|
expect(
|
||||||
|
exposurePairs.first,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(1, StopType.full),
|
||||||
|
ShutterSpeedValue(2, true, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
exposurePairs.last,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(5.6, StopType.full),
|
||||||
|
ShutterSpeedValue(16, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('EV 1.3', () {
|
||||||
|
final exposurePairs = exposurePairsFull(1.3);
|
||||||
|
expect(
|
||||||
|
exposurePairs.first,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(1, StopType.full),
|
||||||
|
ShutterSpeedValue(2, true, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
exposurePairs.last,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(5.6, StopType.full),
|
||||||
|
ShutterSpeedValue(16, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('EV 1.5', () {
|
||||||
|
final exposurePairs = exposurePairsFull(1.5);
|
||||||
|
expect(
|
||||||
|
exposurePairs.first,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(1, StopType.full),
|
||||||
|
ShutterSpeedValue(4, true, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
exposurePairs.last,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(8, StopType.full),
|
||||||
|
ShutterSpeedValue(16, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('EV 1.7', () {
|
||||||
|
final exposurePairs = exposurePairsFull(1.7);
|
||||||
|
expect(
|
||||||
|
exposurePairs.first,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(1, StopType.full),
|
||||||
|
ShutterSpeedValue(4, true, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
exposurePairs.last,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(8, StopType.full),
|
||||||
|
ShutterSpeedValue(16, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('EV 2', () {
|
||||||
|
final exposurePairs = exposurePairsFull(2);
|
||||||
|
expect(
|
||||||
|
exposurePairs.first,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(1, StopType.full),
|
||||||
|
ShutterSpeedValue(4, true, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
exposurePairs.last,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(8, StopType.full),
|
||||||
|
ShutterSpeedValue(16, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
group("StopType.half", () {
|
||||||
|
List<ExposurePair> exposurePairsFull(double ev) =>
|
||||||
|
MeteringContainerBuidler.buildExposureValues(
|
||||||
|
ev,
|
||||||
|
StopType.half,
|
||||||
|
defaultEquipmentProfile,
|
||||||
|
const Film.other(),
|
||||||
|
);
|
||||||
|
|
||||||
|
test('EV 1', () {
|
||||||
|
final exposurePairs = exposurePairsFull(1);
|
||||||
|
expect(
|
||||||
|
exposurePairs.first,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(1, StopType.full),
|
||||||
|
ShutterSpeedValue(2, true, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
exposurePairs.last,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(5.6, StopType.full),
|
||||||
|
ShutterSpeedValue(16, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('EV 1.3', () {
|
||||||
|
final exposurePairs = exposurePairsFull(1.3);
|
||||||
|
expect(
|
||||||
|
exposurePairs.first,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(1, StopType.full),
|
||||||
|
ShutterSpeedValue(3, true, StopType.half),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
exposurePairs.last,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(6.7, StopType.full),
|
||||||
|
ShutterSpeedValue(16, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('EV 1.5', () {
|
||||||
|
final exposurePairs = exposurePairsFull(1.5);
|
||||||
|
expect(
|
||||||
|
exposurePairs.first,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(1, StopType.full),
|
||||||
|
ShutterSpeedValue(3, true, StopType.half),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
exposurePairs.last,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(6.7, StopType.full),
|
||||||
|
ShutterSpeedValue(16, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('EV 1.7', () {
|
||||||
|
final exposurePairs = exposurePairsFull(1.7);
|
||||||
|
expect(
|
||||||
|
exposurePairs.first,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(1, StopType.full),
|
||||||
|
ShutterSpeedValue(3, true, StopType.half),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
exposurePairs.last,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(6.7, StopType.full),
|
||||||
|
ShutterSpeedValue(16, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('EV 2', () {
|
||||||
|
final exposurePairs = exposurePairsFull(2);
|
||||||
|
expect(
|
||||||
|
exposurePairs.first,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(1, StopType.full),
|
||||||
|
ShutterSpeedValue(4, true, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
exposurePairs.last,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(8, StopType.full),
|
||||||
|
ShutterSpeedValue(16, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
group("StopType.third", () {
|
||||||
|
List<ExposurePair> exposurePairsFull(double ev) =>
|
||||||
|
MeteringContainerBuidler.buildExposureValues(
|
||||||
|
ev,
|
||||||
|
StopType.third,
|
||||||
|
defaultEquipmentProfile,
|
||||||
|
const Film.other(),
|
||||||
|
);
|
||||||
|
|
||||||
|
test('EV 1', () {
|
||||||
|
final exposurePairs = exposurePairsFull(1);
|
||||||
|
expect(
|
||||||
|
exposurePairs.first,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(1, StopType.full),
|
||||||
|
ShutterSpeedValue(2, true, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
exposurePairs.last,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(5.6, StopType.full),
|
||||||
|
ShutterSpeedValue(16, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('EV 1.3', () {
|
||||||
|
final exposurePairs = exposurePairsFull(1.3);
|
||||||
|
expect(
|
||||||
|
exposurePairs.first,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(1, StopType.full),
|
||||||
|
ShutterSpeedValue(2.5, true, StopType.third),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
exposurePairs.last,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(6.3, StopType.third),
|
||||||
|
ShutterSpeedValue(16, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('EV 1.5', () {
|
||||||
|
final exposurePairs = exposurePairsFull(1.5);
|
||||||
|
expect(
|
||||||
|
exposurePairs.first,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(1, StopType.full),
|
||||||
|
ShutterSpeedValue(3, true, StopType.third),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
exposurePairs.last,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(7.1, StopType.third),
|
||||||
|
ShutterSpeedValue(16, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('EV 1.7', () {
|
||||||
|
final exposurePairs = exposurePairsFull(1.7);
|
||||||
|
expect(
|
||||||
|
exposurePairs.first,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(1, StopType.full),
|
||||||
|
ShutterSpeedValue(3, true, StopType.third),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
exposurePairs.last,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(7.1, StopType.third),
|
||||||
|
ShutterSpeedValue(16, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('EV 2', () {
|
||||||
|
final exposurePairs = exposurePairsFull(2);
|
||||||
|
expect(
|
||||||
|
exposurePairs.first,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(1, StopType.full),
|
||||||
|
ShutterSpeedValue(4, true, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
exposurePairs.last,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(8, StopType.full),
|
||||||
|
ShutterSpeedValue(16, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
group('Reduced equipment profile', () {
|
||||||
|
final equipmentProfile = EquipmentProfileData(
|
||||||
|
id: "1",
|
||||||
|
name: 'Test1',
|
||||||
|
apertureValues: ApertureValue.values.sublist(4),
|
||||||
|
ndValues: NdValue.values,
|
||||||
|
shutterSpeedValues: ShutterSpeedValue.values.sublist(0, ShutterSpeedValue.values.length - 4),
|
||||||
|
isoValues: IsoValue.values,
|
||||||
|
);
|
||||||
|
|
||||||
|
group("StopType.full", () {
|
||||||
|
List<ExposurePair> exposurePairsFull(double ev) =>
|
||||||
|
MeteringContainerBuidler.buildExposureValues(
|
||||||
|
ev,
|
||||||
|
StopType.full,
|
||||||
|
equipmentProfile,
|
||||||
|
const Film.other(),
|
||||||
|
);
|
||||||
|
|
||||||
|
test('EV 1', () {
|
||||||
|
final exposurePairs = exposurePairsFull(1);
|
||||||
|
expect(
|
||||||
|
exposurePairs.first,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(1.4, StopType.full),
|
||||||
|
ShutterSpeedValue(1, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
exposurePairs.last,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(4, StopType.full),
|
||||||
|
ShutterSpeedValue(8, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('EV 1.3', () {
|
||||||
|
final exposurePairs = exposurePairsFull(1.3);
|
||||||
|
expect(
|
||||||
|
exposurePairs.first,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(1.4, StopType.full),
|
||||||
|
ShutterSpeedValue(1, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
exposurePairs.last,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(4, StopType.full),
|
||||||
|
ShutterSpeedValue(8, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('EV 1.5', () {
|
||||||
|
final exposurePairs = exposurePairsFull(1.5);
|
||||||
|
expect(
|
||||||
|
exposurePairs.first,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(1.4, StopType.full),
|
||||||
|
ShutterSpeedValue(2, true, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
exposurePairs.last,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(5.6, StopType.full),
|
||||||
|
ShutterSpeedValue(8, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('EV 1.7', () {
|
||||||
|
final exposurePairs = exposurePairsFull(1.7);
|
||||||
|
expect(
|
||||||
|
exposurePairs.first,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(1.4, StopType.full),
|
||||||
|
ShutterSpeedValue(2, true, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
exposurePairs.last,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(5.6, StopType.full),
|
||||||
|
ShutterSpeedValue(8, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('EV 2', () {
|
||||||
|
final exposurePairs = exposurePairsFull(2);
|
||||||
|
expect(
|
||||||
|
exposurePairs.first,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(1.4, StopType.full),
|
||||||
|
ShutterSpeedValue(2, true, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
exposurePairs.last,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(5.6, StopType.full),
|
||||||
|
ShutterSpeedValue(8, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
group("StopType.half", () {
|
||||||
|
List<ExposurePair> exposurePairsFull(double ev) =>
|
||||||
|
MeteringContainerBuidler.buildExposureValues(
|
||||||
|
ev,
|
||||||
|
StopType.half,
|
||||||
|
equipmentProfile,
|
||||||
|
const Film.other(),
|
||||||
|
);
|
||||||
|
|
||||||
|
test('EV 1', () {
|
||||||
|
final exposurePairs = exposurePairsFull(1);
|
||||||
|
expect(
|
||||||
|
exposurePairs.first,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(1.4, StopType.full),
|
||||||
|
ShutterSpeedValue(1, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
exposurePairs.last,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(4.0, StopType.full),
|
||||||
|
ShutterSpeedValue(8, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('EV 1.3', () {
|
||||||
|
final exposurePairs = exposurePairsFull(1.3);
|
||||||
|
expect(
|
||||||
|
exposurePairs.first,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(1.4, StopType.full),
|
||||||
|
ShutterSpeedValue(1.5, true, StopType.half),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
exposurePairs.last,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(4.8, StopType.full),
|
||||||
|
ShutterSpeedValue(8, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('EV 1.5', () {
|
||||||
|
final exposurePairs = exposurePairsFull(1.5);
|
||||||
|
expect(
|
||||||
|
exposurePairs.first,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(1.4, StopType.full),
|
||||||
|
ShutterSpeedValue(1.5, true, StopType.half),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
exposurePairs.last,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(4.8, StopType.full),
|
||||||
|
ShutterSpeedValue(8, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('EV 1.7', () {
|
||||||
|
final exposurePairs = exposurePairsFull(1.7);
|
||||||
|
expect(
|
||||||
|
exposurePairs.first,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(1.4, StopType.full),
|
||||||
|
ShutterSpeedValue(1.5, true, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
exposurePairs.last,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(4.8, StopType.full),
|
||||||
|
ShutterSpeedValue(8, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('EV 2', () {
|
||||||
|
final exposurePairs = exposurePairsFull(2);
|
||||||
|
expect(
|
||||||
|
exposurePairs.first,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(1.4, StopType.full),
|
||||||
|
ShutterSpeedValue(2, true, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
exposurePairs.last,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(5.6, StopType.full),
|
||||||
|
ShutterSpeedValue(8, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
group("StopType.third", () {
|
||||||
|
List<ExposurePair> exposurePairsFull(double ev) =>
|
||||||
|
MeteringContainerBuidler.buildExposureValues(
|
||||||
|
ev,
|
||||||
|
StopType.third,
|
||||||
|
equipmentProfile,
|
||||||
|
const Film.other(),
|
||||||
|
);
|
||||||
|
|
||||||
|
test('EV 1', () {
|
||||||
|
final exposurePairs = exposurePairsFull(1);
|
||||||
|
expect(
|
||||||
|
exposurePairs.first,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(1.4, StopType.full),
|
||||||
|
ShutterSpeedValue(1, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
exposurePairs.last,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(4, StopType.full),
|
||||||
|
ShutterSpeedValue(8, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('EV 1.3', () {
|
||||||
|
final exposurePairs = exposurePairsFull(1.3);
|
||||||
|
expect(
|
||||||
|
exposurePairs.first,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(1.4, StopType.full),
|
||||||
|
ShutterSpeedValue(1.3, true, StopType.third),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
exposurePairs.last,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(4.5, StopType.third),
|
||||||
|
ShutterSpeedValue(8, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('EV 1.5', () {
|
||||||
|
final exposurePairs = exposurePairsFull(1.5);
|
||||||
|
expect(
|
||||||
|
exposurePairs.first,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(1.4, StopType.full),
|
||||||
|
ShutterSpeedValue(1.6, true, StopType.third),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
exposurePairs.last,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(5.0, StopType.third),
|
||||||
|
ShutterSpeedValue(8, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('EV 1.7', () {
|
||||||
|
final exposurePairs = exposurePairsFull(1.7);
|
||||||
|
expect(
|
||||||
|
exposurePairs.first,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(1.4, StopType.full),
|
||||||
|
ShutterSpeedValue(1.6, true, StopType.third),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
exposurePairs.last,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(5.0, StopType.third),
|
||||||
|
ShutterSpeedValue(8, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('EV 2', () {
|
||||||
|
final exposurePairs = exposurePairsFull(2);
|
||||||
|
expect(
|
||||||
|
exposurePairs.first,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(1.4, StopType.full),
|
||||||
|
ShutterSpeedValue(2, true, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
exposurePairs.last,
|
||||||
|
const ExposurePair(
|
||||||
|
ApertureValue(5.6, StopType.full),
|
||||||
|
ShutterSpeedValue(8, false, StopType.full),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in a new issue