MotorSignal-App/test/replay_apex_grading_test.dart

131 lines
3.7 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:motorcycle_dash/features/replay/replay_screen.dart';
import 'package:motorcycle_dash/database/database.dart';
void main() {
group('Forensic Replay Apex Grading (MOB-13)', () {
test('CornerAnalysis initializes and grades cornering efficiency accurately', () {
final cornerA = CornerAnalysis(
id: 1,
direction: 'Left',
entrySpeed: 52.0,
apexSpeed: 48.0,
exitSpeed: 54.0,
apexLeanAngle: 42.0,
grade: 'A+',
startIndex: 10,
apexIndex: 25,
endIndex: 40,
);
expect(cornerA.id, 1);
expect(cornerA.direction, 'Left');
expect(cornerA.entrySpeed, 52.0);
expect(cornerA.apexSpeed, 48.0);
expect(cornerA.exitSpeed, 54.0);
expect(cornerA.speedDelta, 2.0);
expect(cornerA.apexLeanAngle, 42.0);
expect(cornerA.grade, 'A+');
expect(cornerA.getGradeColor(), const Color(0xFF10B981)); // Emerald
final cornerB = CornerAnalysis(
id: 2,
direction: 'Right',
entrySpeed: 45.0,
apexSpeed: 40.0,
exitSpeed: 44.0,
apexLeanAngle: 24.0,
grade: 'B',
startIndex: 50,
apexIndex: 65,
endIndex: 80,
);
expect(cornerB.grade, 'B');
expect(cornerB.getGradeColor(), Colors.cyanAccent);
final cornerC = CornerAnalysis(
id: 3,
direction: 'Left',
entrySpeed: 40.0,
apexSpeed: 30.0,
exitSpeed: 32.0,
apexLeanAngle: 18.0,
grade: 'C',
startIndex: 90,
apexIndex: 105,
endIndex: 120,
);
expect(cornerC.grade, 'C');
expect(cornerC.getGradeColor(), Colors.amberAccent);
final cornerD = CornerAnalysis(
id: 4,
direction: 'Right',
entrySpeed: 55.0,
apexSpeed: 25.0,
exitSpeed: 28.0,
apexLeanAngle: 22.0,
grade: 'D',
startIndex: 130,
apexIndex: 145,
endIndex: 160,
);
expect(cornerD.grade, 'D');
expect(cornerD.getGradeColor(), const Color(0xFFFF334B)); // Red
});
test('Telemetry sample sequence with curves generates correct corner breakdown and heatmap tiers', () {
final now = DateTime.now();
final samples = <TelemetrySample>[];
// 1. Straight section (lean <= 20)
for (int i = 0; i < 10; i++) {
samples.add(TelemetrySample(
id: i,
rideId: 1,
timestamp: now.add(Duration(milliseconds: i * 50)),
latitude: 35.0 + (i * 0.0001),
longitude: -84.0 + (i * 0.0001),
speed: 50.0,
leanAngle: 5.0, // Straight/mild -> Yellow
));
}
// 2. Corner 1: Left turn reaching 38 degrees (Apex > 35 -> Red tier)
for (int i = 10; i < 25; i++) {
final lean = -15.0 - (i - 10) * 1.5; // reaches -37.5°
samples.add(TelemetrySample(
id: i,
rideId: 1,
timestamp: now.add(Duration(milliseconds: i * 50)),
latitude: 35.0 + (i * 0.0001),
longitude: -84.0 + (i * 0.0001),
speed: 42.0,
leanAngle: lean,
));
}
// 3. Straight recovery
for (int i = 25; i < 35; i++) {
samples.add(TelemetrySample(
id: i,
rideId: 1,
timestamp: now.add(Duration(milliseconds: i * 50)),
latitude: 35.0 + (i * 0.0001),
longitude: -84.0 + (i * 0.0001),
speed: 48.0,
leanAngle: 4.0,
));
}
expect(samples.length, 35);
final hasApexSample = samples.any((s) => (s.leanAngle ?? 0.0).abs() > 35.0);
expect(hasApexSample, isTrue);
});
});
}