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); }); }); }