Files
eatvio_app/test/features/insights/domain/insights_text_builder_test.dart
2026-11-09 15:35:10 +03:00

286 lines
9.0 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'package:eatvio_app/features/insights/domain/insights_text_builder.dart';
import 'package:eatvio_app/features/insights/models/insights_period.dart';
import 'package:eatvio_app/features/profile/models/circumference_model.dart';
import 'package:eatvio_app/features/profile/models/weight_model.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
WeightModel _weight(double weight, {double? bmi, int day = 1}) {
final date = DateTime(2026, 11, day, 12);
return WeightModel(
id: day,
userId: 1,
weight: weight,
createdAt: date,
updatedAt: date,
bmi: bmi,
);
}
CircumferenceModel _circumference({
double waist = 80,
double chest = 95,
double hips = 100,
int day = 1,
}) {
final date = DateTime(2026, 11, day, 12);
return CircumferenceModel(
id: day,
userId: 1,
chestCircumference: chest,
waistCircumference: waist,
hipCircumference: hips,
createdAt: date,
updatedAt: date,
);
}
void main() {
late InsightsTextBuilder builder;
setUpAll(() async {
final s = await S.load(const Locale('ru'));
builder = InsightsTextBuilder(s);
});
group('форматирование', () {
test('formatNumber: один знак без хвостового нуля', () {
expect(builder.formatNumber(3), '3');
expect(builder.formatNumber(3.5), '3.5');
expect(builder.formatNumber(3.04), '3');
expect(builder.formatNumber(3.26), '3.3');
});
test('formatLabel: dd.MM', () {
expect(builder.formatLabel(DateTime(2026, 11, 9, 12)), '09.11');
});
test('periodLabel: все периоды', () {
expect(builder.periodLabel(BodyPeriod.month), 'месяц');
expect(builder.periodLabel(BodyPeriod.threeMonths), '3 месяца');
expect(builder.periodLabel(BodyPeriod.sixMonths), '6 месяцев');
expect(builder.periodLabel(BodyPeriod.year), 'год');
expect(builder.periodLabel(BodyPeriod.all), 'всё время');
});
});
group('вес', () {
test('снижение', () {
final model = builder.buildWeight([
_weight(74.5),
_weight(73.2, day: 9),
], BodyPeriod.month);
expect(model.deltaText, 'Снизили на 1.3 кг за месяц');
expect(model.delta, -1.3);
expect(model.last, 73.2);
expect(model.headline, '73.2');
expect(model.unit, 'кг');
expect(model.labels, ['01.11', '09.11']);
expect(model.values, [74.5, 73.2]);
});
test('набор', () {
final model = builder.buildWeight([
_weight(70),
_weight(72, day: 3),
], BodyPeriod.threeMonths);
expect(model.deltaText, 'Набрали 2 кг за 3 месяца');
expect(model.delta, 2);
});
test('порог 0.05: меньше — не изменился', () {
final model = builder.buildWeight([
_weight(70),
_weight(70.04, day: 3),
], BodyPeriod.year);
expect(model.deltaText, 'Вес не изменился за год');
});
test('порог 0.05: ровно 0.25 — уже изменение', () {
final model = builder.buildWeight([
_weight(70),
_weight(70.25, day: 3),
], BodyPeriod.all);
expect(model.deltaText, 'Набрали 0.3 кг за всё время');
});
test('одна точка: недостаточно данных, но headline есть', () {
final model = builder.buildWeight([_weight(72)], BodyPeriod.month);
expect(model.deltaText, 'Недостаточно данных');
expect(model.delta, isNull);
expect(model.headline, '72.0');
});
test('нет точек', () {
final model = builder.buildWeight([], BodyPeriod.month);
expect(model.deltaText, 'Недостаточно данных');
expect(model.last, isNull);
expect(model.headline, '—');
expect(model.values, isEmpty);
});
});
group('категории ИМТ (границы)', () {
final cases = <double, String>{
15.9: 'выраженный дефицит массы',
16.0: 'недостаточная масса',
18.4: 'недостаточная масса',
18.5: 'норма',
24.9: 'норма',
25.0: 'избыточная масса',
29.9: 'избыточная масса',
30.0: 'ожирение I ст.',
34.9: 'ожирение I ст.',
35.0: 'ожирение II ст.',
39.9: 'ожирение II ст.',
40.0: 'ожирение III ст.',
55.0: 'ожирение III ст.',
};
cases.forEach((bmi, expected) {
test('$bmi → $expected', () {
expect(builder.bmiCategory(bmi), expected);
});
});
});
group('ИМТ', () {
test('без роста: пусто и подсказка', () {
final model = builder.buildBmi(
[_weight(70, bmi: 22)],
BodyPeriod.month,
null,
);
expect(model.values, isEmpty);
expect(model.headline, '—');
expect(model.hint, 'Укажите рост, чтобы посчитать ИМТ.');
expect(model.deltaText, 'Укажите рост, чтобы посчитать ИМТ.');
expect(model.category, isNull);
});
test('нулевой рост считается отсутствующим', () {
final model = builder.buildBmi(
[_weight(70, bmi: 22)],
BodyPeriod.month,
0,
);
expect(model.values, isEmpty);
});
test('ИМТ ниже', () {
final model = builder.buildBmi(
[_weight(80, bmi: 26.5), _weight(75, bmi: 24.2, day: 5)],
BodyPeriod.threeMonths,
176,
);
expect(model.deltaText, 'ИМТ ниже на 2.3 за 3 месяца · норма');
expect(model.category, 'норма');
expect(model.headline, '24.2');
expect(model.last, 24.2);
expect(model.delta, -2.3);
expect(model.hint, contains('Считаем при росте 176 см.'));
});
test('ИМТ выше', () {
final model = builder.buildBmi(
[_weight(70, bmi: 24), _weight(80, bmi: 27, day: 5)],
BodyPeriod.month,
170,
);
expect(model.deltaText, 'ИМТ выше на 3 за месяц · избыточная масса');
});
test('ИМТ не изменился', () {
final model = builder.buildBmi(
[_weight(70, bmi: 22), _weight(70, bmi: 22.01, day: 5)],
BodyPeriod.year,
170,
);
expect(model.deltaText, 'ИМТ не изменился за год · норма');
});
test('точки с bmi = null пропускаются', () {
final model = builder.buildBmi(
[_weight(70, bmi: null), _weight(71, bmi: 22, day: 3)],
BodyPeriod.month,
170,
);
expect(model.values, [22]);
expect(model.labels, ['03.11']);
expect(model.deltaText, 'Недостаточно данных');
});
test('рост есть, точек нет', () {
final model = builder.buildBmi([], BodyPeriod.month, 170);
expect(model.values, isEmpty);
expect(model.deltaText, 'Недостаточно данных');
expect(model.hint, contains('170'));
});
});
group('замеры', () {
test('по каждой части: меньше / больше / без изменений', () {
final model = builder.buildMeasure([
_circumference(waist: 82, chest: 96, hips: 100),
_circumference(waist: 80.5, chest: 98, hips: 100, day: 9),
], BodyPeriod.month);
expect(
model.deltaText,
'Талия меньше на 1.5 см, Грудь больше на 2 см, Бёдра без изменений за месяц',
);
expect(model.headline, '81');
expect(model.waist, [82, 80.5]);
expect(model.labels, ['01.11', '09.11']);
});
test('одна точка — недостаточно данных', () {
final model = builder.buildMeasure([_circumference()], BodyPeriod.month);
expect(model.deltaText, 'Недостаточно данных');
expect(model.headline, '80');
});
test('нет точек', () {
final model = builder.buildMeasure([], BodyPeriod.month);
expect(model.headline, '—');
expect(model.deltaText, 'Недостаточно данных');
});
});
group('build', () {
test('сортирует по дате, daily/intra = null', () {
final payload = builder.build(
weights: [_weight(73, bmi: 23, day: 9), _weight(75, bmi: 24, day: 1)],
circumferences: [
_circumference(waist: 79, day: 9),
_circumference(waist: 81),
],
period: BodyPeriod.month,
heightCm: 175,
);
expect(payload.weight.values, [75, 73]);
expect(payload.bmi.values, [24, 23]);
expect(payload.measure.waist, [81, 79]);
expect(payload.daily, isNull);
expect(payload.intra, isNull);
});
});
}