import 'package:flutter_test/flutter_test.dart'; import 'package:add_months/models/models.dart'; import 'package:add_months/risk_engine/risk_engine.dart'; void main() { group('Hazard Ratios', () { test('smoking current produces HR > 1.8', () { expect(getSmokingHR(SmokingStatus.current, 10), greaterThanOrEqualTo(1.8)); }); test('smoking heavy (>20/day) produces highest HR', () { final lightHR = getSmokingHR(SmokingStatus.current, 5); final moderateHR = getSmokingHR(SmokingStatus.current, 15); final heavyHR = getSmokingHR(SmokingStatus.current, 25); expect(heavyHR, greaterThan(moderateHR)); expect(moderateHR, greaterThan(lightHR)); expect(heavyHR, equals(2.8)); }); test('never smoker has HR of 1.0', () { expect(getSmokingHR(SmokingStatus.never, 0), equals(1.0)); }); test('sedentary activity has higher HR than active', () { expect( getActivityHR(ActivityLevel.sedentary), greaterThan(getActivityHR(ActivityLevel.high)), ); }); test('very heavy alcohol has highest HR', () { expect(getAlcoholHR(AlcoholLevel.veryHeavy), equals(1.6)); expect(getAlcoholHR(AlcoholLevel.none), equals(1.0)); }); test('short sleep has higher HR than optimal', () { expect(getSleepHR(5.0, true), greaterThan(getSleepHR(7.5, true))); }); test('inconsistent sleep adds to HR', () { expect(getSleepHR(7.0, false), greaterThan(getSleepHR(7.0, true))); }); }); group('Mortality Tables', () { test('Japan is in Group A', () { expect(getCountryGroup('Japan'), equals(MortalityGroup.groupA)); }); test('United States is in Group B', () { expect(getCountryGroup('United States'), equals(MortalityGroup.groupB)); }); test('female LE is higher than male', () { final maleLE = getLifeExpectancyAtBirth(MortalityGroup.groupB, Sex.male); final femaleLE = getLifeExpectancyAtBirth(MortalityGroup.groupB, Sex.female); expect(femaleLE, greaterThan(maleLE)); }); test('remaining LE decreases with age', () { final le30 = getRemainingLifeExpectancy(30, Sex.male, 'United States'); final le50 = getRemainingLifeExpectancy(50, Sex.male, 'United States'); expect(le30, greaterThan(le50)); }); test('getSupportedCountries returns sorted list', () { final countries = getSupportedCountries(); expect(countries, isNotEmpty); expect(countries.first, equals('Argentina')); expect(countries, contains('United States')); }); }); group('Calculator', () { final healthyProfile = UserProfile( age: 40, sex: Sex.male, country: 'United States', heightCm: 175, weightKg: 75, ); final optimalInputs = BehavioralInputs.optimal; final unhealthyInputs = BehavioralInputs( smoking: SmokingStatus.current, cigarettesPerDay: 20, alcohol: AlcoholLevel.heavy, sleepHours: 5.0, sleepConsistent: false, activity: ActivityLevel.sedentary, driving: DrivingExposure.veryHigh, workHours: WorkHoursLevel.extreme, ); test('optimal inputs produce low combined HR', () { final hr = computeCombinedHazard(optimalInputs, 22.0); expect(hr, closeTo(1.0, 0.1)); }); test('unhealthy inputs produce high combined HR', () { final hr = computeCombinedHazard(unhealthyInputs, 35.0); expect(hr, greaterThan(3.0)); }); test('combined HR is capped at 4.0', () { final hr = computeCombinedHazard(unhealthyInputs, 45.0); expect(hr, lessThanOrEqualTo(4.0)); }); test('ranking puts smoking above driving for heavy smoker', () { final smokerInputs = BehavioralInputs( smoking: SmokingStatus.current, cigarettesPerDay: 20, alcohol: AlcoholLevel.none, sleepHours: 7.5, sleepConsistent: true, activity: ActivityLevel.high, driving: DrivingExposure.veryHigh, workHours: WorkHoursLevel.normal, ); final result = calculateRankedFactors(healthyProfile, smokerInputs); expect(result.rankedFactors, isNotEmpty); expect(result.dominantFactor?.behaviorKey, equals('smoking')); }); test('optimal profile returns empty factors', () { final result = calculateRankedFactors(healthyProfile, optimalInputs); expect(result.rankedFactors, isEmpty); }); test('result includes model version', () { final result = calculateRankedFactors(healthyProfile, unhealthyInputs); expect(result.modelVersion, equals('1.0')); }); test('sedentary person sees activity as factor', () { final sedentaryInputs = BehavioralInputs( smoking: SmokingStatus.never, cigarettesPerDay: 0, alcohol: AlcoholLevel.none, sleepHours: 7.5, sleepConsistent: true, activity: ActivityLevel.sedentary, driving: DrivingExposure.low, workHours: WorkHoursLevel.normal, ); final result = calculateRankedFactors(healthyProfile, sedentaryInputs); expect(result.rankedFactors, isNotEmpty); expect(result.dominantFactor?.behaviorKey, equals('activity')); }); test('delta ranges are reasonable', () { final result = calculateRankedFactors(healthyProfile, unhealthyInputs); for (final factor in result.rankedFactors) { // Low should be less than or equal to high expect(factor.delta.lowMonths, lessThanOrEqualTo(factor.delta.highMonths)); // Months should be reasonable (not hundreds of years) expect(factor.delta.highMonths, lessThan(240)); // < 20 years } }); }); group('Existing Conditions', () { test('cardiovascular disease increases diagnosis HR', () { final hr = getDiagnosisHR({Diagnosis.cardiovascular}); expect(hr, equals(1.5)); }); test('multiple conditions compound', () { final singleHR = getDiagnosisHR({Diagnosis.diabetes}); final multiHR = getDiagnosisHR({Diagnosis.diabetes, Diagnosis.hypertension}); expect(multiHR, greaterThan(singleHR)); }); test('conditions reduce effective baseline', () { final healthyProfile = UserProfile( age: 50, sex: Sex.male, country: 'United States', heightCm: 175, weightKg: 80, diagnoses: {}, ); final unhealthyProfile = healthyProfile.copyWith( diagnoses: {Diagnosis.cardiovascular, Diagnosis.diabetes}, ); final sedentaryInputs = BehavioralInputs( smoking: SmokingStatus.never, cigarettesPerDay: 0, alcohol: AlcoholLevel.none, sleepHours: 7.5, sleepConsistent: true, activity: ActivityLevel.sedentary, driving: DrivingExposure.low, workHours: WorkHoursLevel.normal, ); final healthyResult = calculateRankedFactors(healthyProfile, sedentaryInputs); final unhealthyResult = calculateRankedFactors(unhealthyProfile, sedentaryInputs); // Unhealthy person has less to gain (lower baseline) if (healthyResult.dominantFactor != null && unhealthyResult.dominantFactor != null) { expect( unhealthyResult.dominantFactor!.delta.highMonths, lessThan(healthyResult.dominantFactor!.delta.highMonths), ); } }); }); }