MotorSignal-App/test/curvy_route_twistiness_elev...

158 lines
5.6 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:motorcycle_dash/core/theme/theme_extensions.dart';
import 'package:motorcycle_dash/services/map/map_provider_interface.dart';
import 'package:motorcycle_dash/services/routes/route_models.dart';
import 'package:motorcycle_dash/features/routes/models/route_curvature_analysis.dart';
import 'package:motorcycle_dash/features/routes/widgets/curviness_priority_selector.dart';
import 'package:motorcycle_dash/features/routes/widgets/route_curvature_summary_card.dart';
import 'package:motorcycle_dash/features/routes/widgets/route_elevation_chart.dart';
void main() {
group('MOB-17: Route Curvature & Twistiness Analysis Model', () {
test('analyzes polyline geometry and classifies corners and switchbacks', () {
// Create a winding mountain path with hairpin turns
final points = [
const AppLatLng(37.7749, -122.4194),
const AppLatLng(37.7760, -122.4180),
const AppLatLng(37.7755, -122.4160), // sharp right bend
const AppLatLng(37.7770, -122.4165), // sharp left hairpin
const AppLatLng(37.7780, -122.4140),
const AppLatLng(37.7795, -122.4145),
];
final report = RouteCurvatureReport.analyze(
geometry: points,
priority: CurvinessPriority.curvy,
);
expect(report.totalCorners, greaterThan(0));
expect(report.twistinessIndex, greaterThan(1.0));
expect(report.elevationProfile, isNotEmpty);
expect(report.totalElevationGainMeters, greaterThan(0.0));
expect(report.formattedCornerCount, contains('Corners'));
expect(report.formattedElevationGain, contains('ft'));
});
test('priority multiplier scales twistiness for Extreme Passes', () {
final stops = [
const RouteStop(id: 's1', displayName: 'Base', latitude: 36.1, longitude: -118.2),
const RouteStop(id: 's2', displayName: 'Ridge', latitude: 36.2, longitude: -118.3),
const RouteStop(id: 's3', displayName: 'Peak', latitude: 36.3, longitude: -118.4),
];
final standardReport = RouteCurvatureReport.analyze(
geometry: const [],
stops: stops,
priority: CurvinessPriority.standard,
);
final extremeReport = RouteCurvatureReport.analyze(
geometry: const [],
stops: stops,
priority: CurvinessPriority.extremePasses,
);
expect(extremeReport.twistinessIndex, greaterThan(standardReport.twistinessIndex));
expect(extremeReport.totalCorners, greaterThanOrEqualTo(standardReport.totalCorners));
});
});
group('MOB-17: Curvy Route Widgets Rendering', () {
const colors = MotorSignalThemeColors.dark;
testWidgets('CurvinessPrioritySelector switches between priorities', (tester) async {
CurvinessPriority selected = CurvinessPriority.standard;
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: StatefulBuilder(
builder: (context, setState) {
return CurvinessPrioritySelector(
selected: selected,
onChanged: (p) => setState(() => selected = p),
colors: colors,
);
},
),
),
),
);
expect(find.text('CURVINESS PRIORITY'), findsOneWidget);
expect(find.text('Standard'), findsOneWidget);
expect(find.text('Curvy'), findsOneWidget);
expect(find.text('Extreme Passes'), findsOneWidget);
await tester.tap(find.text('Curvy'));
await tester.pumpAndSettle();
expect(selected, CurvinessPriority.curvy);
await tester.tap(find.text('Extreme Passes'));
await tester.pumpAndSettle();
expect(selected, CurvinessPriority.extremePasses);
});
testWidgets('RouteElevationChart displays gain, loss, and distance labels', (tester) async {
final report = RouteCurvatureReport.analyze(
geometry: [
const AppLatLng(34.05, -118.25),
const AppLatLng(34.10, -118.30),
const AppLatLng(34.15, -118.35),
],
);
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: RouteElevationChart(
report: report,
colors: colors,
isDark: true,
),
),
),
);
expect(find.text('ELEVATION PROFILE'), findsOneWidget);
expect(find.textContaining('Gain: +'), findsOneWidget);
expect(find.textContaining('0.0 mi (Start)'), findsOneWidget);
});
testWidgets('RouteCurvatureSummaryCard displays total corners and twistiness index', (tester) async {
final report = RouteCurvatureReport.analyze(
geometry: [
const AppLatLng(37.77, -122.41),
const AppLatLng(37.80, -122.45),
const AppLatLng(37.82, -122.48),
],
priority: CurvinessPriority.curvy,
);
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: SingleChildScrollView(
child: RouteCurvatureSummaryCard(
report: report,
colors: colors,
isDark: true,
showElevationChart: true,
),
),
),
),
);
expect(find.text('CURVATURE & ELEVATION'), findsOneWidget);
expect(find.text('TOTAL CORNERS'), findsOneWidget);
expect(find.text('TWISTINESS INDEX'), findsOneWidget);
expect(find.text('Hairpins'), findsOneWidget);
expect(find.text('Bends'), findsOneWidget);
expect(find.text('Sweepers'), findsOneWidget);
expect(find.text('ELEVATION PROFILE'), findsOneWidget);
});
});
}