diff --git a/lib/models/exercises/exercise.dart b/lib/models/exercises/exercise.dart index e642dd15..74e269f2 100644 --- a/lib/models/exercises/exercise.dart +++ b/lib/models/exercises/exercise.dart @@ -147,21 +147,21 @@ class Exercise extends Equatable { Exercise.fromApiDataJson(Map<String, dynamic> baseData, List<Language> languages) : this.fromApiData(ExerciseApiData.fromJson(baseData), languages); - Exercise.fromApiData(ExerciseApiData baseData, List<Language> languages) { - id = baseData.id; - uuid = baseData.uuid; - categoryId = baseData.category.id; - category = baseData.category; - - created = baseData.created; - lastUpdate = baseData.lastUpdate; - lastUpdateGlobal = baseData.lastUpdateGlobal; - - musclesSecondary = baseData.muscles; - muscles = baseData.muscles; - equipment = baseData.equipment; - category = baseData.category; - translations = baseData.translations.map((e) { + Exercise.fromApiData(ExerciseApiData exerciseData, List<Language> languages) { + id = exerciseData.id; + uuid = exerciseData.uuid; + categoryId = exerciseData.category.id; + category = exerciseData.category; + + created = exerciseData.created; + lastUpdate = exerciseData.lastUpdate; + lastUpdateGlobal = exerciseData.lastUpdateGlobal; + + musclesSecondary = exerciseData.muscles; + muscles = exerciseData.muscles; + equipment = exerciseData.equipment; + category = exerciseData.category; + translations = exerciseData.translations.map((e) { e.language = languages.firstWhere( (l) => l.id == e.languageId, @@ -173,13 +173,13 @@ class Exercise extends Equatable { ); return e; }).toList(); - videos = baseData.videos; - images = baseData.images; + videos = exerciseData.videos; + images = exerciseData.images; - authors = baseData.authors; - authorsGlobal = baseData.authorsGlobal; + authors = exerciseData.authors; + authorsGlobal = exerciseData.authorsGlobal; - variationId = baseData.variationId; + variationId = exerciseData.variationId; } /// Returns translation for the given language diff --git a/lib/models/workouts/log.dart b/lib/models/workouts/log.dart index 81c82767..615549a9 100644 --- a/lib/models/workouts/log.dart +++ b/lib/models/workouts/log.dart @@ -17,6 +17,7 @@ */ import 'package:json_annotation/json_annotation.dart'; +import 'package:wger/helpers/consts.dart'; import 'package:wger/helpers/json.dart'; import 'package:wger/helpers/misc.dart'; import 'package:wger/models/exercises/exercise.dart'; @@ -86,12 +87,12 @@ class Log { required this.routineId, this.repetitions, this.repetitionsTarget, - required this.repetitionsUnitId, + this.repetitionsUnitId = REP_UNIT_REPETITIONS_ID, required this.rir, this.rirTarget, this.weight, this.weightTarget, - required this.weightUnitId, + this.weightUnitId = WEIGHT_UNIT_KG, required this.date, }); diff --git a/lib/models/workouts/log.g.dart b/lib/models/workouts/log.g.dart index e2656f18..410af19d 100644 --- a/lib/models/workouts/log.g.dart +++ b/lib/models/workouts/log.g.dart @@ -32,12 +32,12 @@ Log _$LogFromJson(Map<String, dynamic> json) { routineId: (json['routine'] as num).toInt(), repetitions: stringToNum(json['repetitions'] as String?), repetitionsTarget: stringToNum(json['repetitions_target'] as String?), - repetitionsUnitId: (json['repetitions_unit'] as num).toInt(), + repetitionsUnitId: (json['repetitions_unit'] as num?)?.toInt() ?? REP_UNIT_REPETITIONS_ID, rir: json['rir'] as String?, rirTarget: json['rir_target'] as String?, weight: stringToNum(json['weight'] as String?), weightTarget: stringToNum(json['weight_target'] as String?), - weightUnitId: (json['weight_unit'] as num).toInt(), + weightUnitId: (json['weight_unit'] as num?)?.toInt() ?? WEIGHT_UNIT_KG, date: DateTime.parse(json['date'] as String), ); } diff --git a/lib/models/workouts/routine.dart b/lib/models/workouts/routine.dart index 9af1492d..bf4b738a 100644 --- a/lib/models/workouts/routine.dart +++ b/lib/models/workouts/routine.dart @@ -118,8 +118,8 @@ class Routine { /// means here that the values are the same, i.e. logs with the same weight, /// reps, etc. are considered equal. Workout ID, Log ID and date are not /// considered. - List<Log> filterLogsByExercise(Exercise exercise, {bool unique = false}) { - var out = logs.where((element) => element.exerciseId == exercise.id).toList(); + List<Log> filterLogsByExercise(int exerciseId, {bool unique = false}) { + var out = logs.where((log) => log.exerciseId == exerciseId).toList(); if (unique) { out = out.toSet().toList(); @@ -129,6 +129,26 @@ class Routine { return out; } + /// Groups logs by repetition + Map<num, List<Log>> groupLogsByRepetition({List<Log>? logs}) { + final workoutLogs = logs ?? this.logs; + final Map<num, List<Log>> groupedLogs = {}; + + for (final log in workoutLogs) { + if (log.repetitions == null) { + continue; + } + + if (!groupedLogs.containsKey(log.repetitions)) { + groupedLogs[log.repetitions!] = []; + } + + groupedLogs[log.repetitions]!.add(log); + } + + return groupedLogs; + } + /// Massages the log data to more easily present on the log overview /// Map<DateTime, Map<String, dynamic>> get logData { diff --git a/lib/providers/routines.dart b/lib/providers/routines.dart index 0cd67895..4723aa2f 100644 --- a/lib/providers/routines.dart +++ b/lib/providers/routines.dart @@ -23,7 +23,6 @@ import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:wger/exceptions/http_exception.dart'; import 'package:wger/helpers/consts.dart'; -import 'package:wger/models/exercises/exercise.dart'; import 'package:wger/models/workouts/base_config.dart'; import 'package:wger/models/workouts/day.dart'; import 'package:wger/models/workouts/day_data.dart'; @@ -62,7 +61,7 @@ class RoutinesProvider with ChangeNotifier { static const _routineConfigRestTime = 'rest-config'; static const _routineConfigMaxRestTime = 'max-rest-config'; - Routine? _currentPlan; + Routine? _currentRoutine; late ExercisesProvider _exercises; final WgerBaseProvider baseProvider; List<Routine> _routines = []; @@ -92,7 +91,7 @@ class RoutinesProvider with ChangeNotifier { /// Clears all lists void clear() { - _currentPlan = null; + _currentRoutine = null; _routines = []; _weightUnits = []; _repetitionUnits = []; @@ -131,17 +130,17 @@ class RoutinesProvider with ChangeNotifier { /// Set the currently "active" workout plan void setCurrentPlan(int id) { - _currentPlan = findById(id); + _currentRoutine = findById(id); } /// Returns the currently "active" workout plan - Routine? get currentPlan { - return _currentPlan; + Routine? get currentRoutine { + return _currentRoutine; } /// Reset the currently "active" workout plan to null void resetCurrentRoutine() { - _currentPlan = null; + _currentRoutine = null; } /// Returns the current active workout plan. At the moment this is just @@ -378,21 +377,6 @@ class RoutinesProvider with ChangeNotifier { } } - Future<Map<String, dynamic>> fetchLogData( - Routine workout, - Exercise base, - ) async { - final data = await baseProvider.fetch( - baseProvider.makeUrl( - _routinesUrlPath, - id: workout.id, - objectMethod: 'logs', - query: {'id': base.id!.toString()}, - ), - ); - return data; - } - /// Fetch and set weight units for workout (kg, lb, plate, etc.) Future<void> fetchAndSetRepetitionUnits() async { final response = diff --git a/lib/widgets/routines/charts.dart b/lib/widgets/routines/charts.dart index e41e249a..41c20a3e 100644 --- a/lib/widgets/routines/charts.dart +++ b/lib/widgets/routines/charts.dart @@ -22,9 +22,10 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:intl/intl.dart'; import 'package:wger/helpers/charts.dart'; import 'package:wger/helpers/colors.dart'; +import 'package:wger/models/workouts/log.dart'; class LogChartWidgetFl extends StatefulWidget { - final Map _data; + final Map<num, List<Log>> _data; final DateTime _currentDate; const LogChartWidgetFl(this._data, this._currentDate); @@ -50,7 +51,7 @@ class _LogChartWidgetFlState extends State<LogChartWidgetFl> { touchTooltipData: LineTouchTooltipData( getTooltipItems: (touchedSpots) { return touchedSpots.map((touchedSpot) { - final reps = widget._data['chart_data'][touchedSpot.barIndex].first['reps']; + final reps = widget._data[touchedSpot.barIndex]?.first.repetitions; return LineTooltipItem( '$reps × ${touchedSpot.y} kg', @@ -63,7 +64,7 @@ class _LogChartWidgetFlState extends State<LogChartWidgetFl> { } LineChartData mainData() { - final colors = generateChartColors(widget._data['chart_data'].length).iterator; + final colors = generateChartColors(widget._data.keys.length).iterator; return LineChartData( lineTouchData: tooltipData(), @@ -101,8 +102,9 @@ class _LogChartWidgetFlState extends State<LogChartWidgetFl> { ); }, interval: chartGetInterval( - DateTime.parse(widget._data['logs'].keys.first), - DateTime.parse(widget._data['logs'].keys.last), + // TODO: make sure this works when the data is empty etc + widget._data[widget._data.keys.first]!.first.date, + widget._data[widget._data.keys.last]!.first.date, ), ), ), @@ -121,14 +123,14 @@ class _LogChartWidgetFlState extends State<LogChartWidgetFl> { border: Border.all(color: const Color(0xff37434d)), ), lineBarsData: [ - ...widget._data['chart_data'].map((e) { + ...widget._data.keys.map((reps) { colors.moveNext(); return LineChartBarData( spots: [ - ...e.map( + ...widget._data[reps]!.map( (entry) => FlSpot( - DateTime.parse(entry['date']).millisecondsSinceEpoch.toDouble(), - double.parse(entry['weight']), + entry.date.millisecondsSinceEpoch.toDouble(), + entry.weight!.toDouble(), ), ), ], diff --git a/lib/widgets/routines/gym_mode.dart b/lib/widgets/routines/gym_mode.dart index ecdbc8eb..0e8db6e8 100644 --- a/lib/widgets/routines/gym_mode.dart +++ b/lib/widgets/routines/gym_mode.dart @@ -533,7 +533,7 @@ class _LogPageState extends State<LogPage> { style: Theme.of(context).textTheme.titleLarge, textAlign: TextAlign.center, ), - ...widget._workoutPlan.filterLogsByExercise(widget._exercise, unique: true).map((log) { + ...widget._workoutPlan.filterLogsByExercise(widget._exercise.id!, unique: true).map((log) { return ListTile( title: Text(log.singleLogRepTextNoNl), subtitle: Text( @@ -646,7 +646,7 @@ class _LogPageState extends State<LogPage> { Text(widget._slotData.comment, textAlign: TextAlign.center), const SizedBox(height: 10), Expanded( - child: (widget._workoutPlan.filterLogsByExercise(widget._exercise).isNotEmpty) + child: (widget._workoutPlan.filterLogsByExercise(widget._exercise.id!).isNotEmpty) ? getPastLogs() : Container(), ), diff --git a/lib/widgets/routines/log.dart b/lib/widgets/routines/log.dart index 8ddb3879..068ae9db 100644 --- a/lib/widgets/routines/log.dart +++ b/lib/widgets/routines/log.dart @@ -18,89 +18,60 @@ import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; -import 'package:provider/provider.dart'; import 'package:wger/helpers/colors.dart'; import 'package:wger/helpers/ui.dart'; import 'package:wger/models/exercises/exercise.dart'; import 'package:wger/models/workouts/log.dart'; +import 'package:wger/models/workouts/routine.dart'; import 'package:wger/models/workouts/session.dart'; -import 'package:wger/providers/routines.dart'; import 'package:wger/widgets/measurements/charts.dart'; import 'package:wger/widgets/routines/charts.dart'; class ExerciseLogChart extends StatelessWidget { - final Exercise _base; - final DateTime _currentDate; + final Map<num, List<Log>> _logs; + final DateTime _selectedDate; - const ExerciseLogChart(this._base, this._currentDate); + const ExerciseLogChart(this._logs, this._selectedDate); @override Widget build(BuildContext context) { - final workoutPlansData = Provider.of<RoutinesProvider>(context, listen: false); - final workout = workoutPlansData.currentPlan; - var colors = generateChartColors(1).iterator; + final colors = generateChartColors(_logs.keys.length).iterator; - Future<Map<String, dynamic>> getChartEntries(BuildContext context) async { - return workoutPlansData.fetchLogData(workout!, _base); - } + return Column( + mainAxisSize: MainAxisSize.max, + children: [ + LogChartWidgetFl(_logs, _selectedDate), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ..._logs.keys.map((reps) { + // e is the list of logs with the same reps, so we can just take the + // first entry and read the reps from it. Yes, this is an amazingly ugly hack + // final reps = log.repetitions; - return FutureBuilder( - future: getChartEntries(context), - builder: (context, AsyncSnapshot<Map<String, dynamic>> snapshot) { - if (snapshot.connectionState == ConnectionState.done) { - colors = generateChartColors(snapshot.data!['chart_data'].length).iterator; - } - - return SizedBox( - height: 260, - child: snapshot.connectionState == ConnectionState.waiting - ? const Center(child: CircularProgressIndicator()) - : Column( - mainAxisSize: MainAxisSize.max, - children: [ - LogChartWidgetFl(snapshot.data!, _currentDate), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ...snapshot.data!['chart_data'].map((e) { - // e is the list of logs with the same reps, so we can just take the - // first entry and read the reps from it. Yes, this is an amazingly ugly hack - final reps = e.first['reps']; - - colors.moveNext(); - return Indicator( - color: colors.current, - text: reps.toString(), - isSquare: false, - ); - }).toList(), - ], - ), - const SizedBox(height: 15), - ], - ), - ); - }, + colors.moveNext(); + return Indicator( + color: colors.current, + text: reps.toString(), + isSquare: false, + ); + }).toList(), + ], + ), + const SizedBox(height: 15), + ], ); } } -class DayLogWidget extends StatefulWidget { +class DayLogWidget extends StatelessWidget { final DateTime _date; + final Routine _routine; + final WorkoutSession? _session; final Map<Exercise, List<Log>> _exerciseData; - const DayLogWidget(this._date, this._exerciseData, this._session); - - @override - _DayLogWidgetState createState() => _DayLogWidgetState(); -} - -class _DayLogWidgetState extends State<DayLogWidget> { - @override - void initState() { - super.initState(); - } + const DayLogWidget(this._date, this._exerciseData, this._session, this._routine); @override Widget build(BuildContext context) { @@ -108,35 +79,36 @@ class _DayLogWidgetState extends State<DayLogWidget> { child: Column( children: [ Text( - DateFormat.yMd(Localizations.localeOf(context).languageCode).format(widget._date), + DateFormat.yMd(Localizations.localeOf(context).languageCode).format(_date), style: Theme.of(context).textTheme.headlineSmall, ), - if (widget._session != null) const Text('Session data here'), - ...widget._exerciseData.keys.map((base) { - final exercise = base.getTranslation(Localizations.localeOf(context).languageCode); + if (_session != null) const Text('Session data here'), + ..._exerciseData.keys.map((exercise) { + final translation = + exercise.getTranslation(Localizations.localeOf(context).languageCode); return Column( children: [ - if (widget._exerciseData[base]!.isNotEmpty) + if (_exerciseData[exercise]!.isNotEmpty) Text( - exercise.name, + translation.name, style: Theme.of(context).textTheme.headlineSmall, ) else Container(), - ...widget._exerciseData[base]!.map( + ..._exerciseData[exercise]!.map( (log) => Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(log.singleLogRepTextNoNl), IconButton( icon: const Icon(Icons.delete), - onPressed: () async { + onPressed: () { showDeleteDialog( context, - exercise.name, + translation.name, log, - exercise, - widget._exerciseData, + translation, + _exerciseData, ); }, ), @@ -145,7 +117,12 @@ class _DayLogWidgetState extends State<DayLogWidget> { ), Padding( padding: const EdgeInsets.symmetric(horizontal: 15), - child: ExerciseLogChart(base, widget._date), + child: ExerciseLogChart( + _routine.groupLogsByRepetition( + logs: _routine.filterLogsByExercise(exercise.id!), + ), + _date, + ), ), ], ); diff --git a/lib/widgets/routines/workout_logs.dart b/lib/widgets/routines/workout_logs.dart index 4479ecce..3be4e395 100644 --- a/lib/widgets/routines/workout_logs.dart +++ b/lib/widgets/routines/workout_logs.dart @@ -28,9 +28,9 @@ import 'package:wger/theme/theme.dart'; import 'package:wger/widgets/routines/log.dart'; class WorkoutLogs extends StatefulWidget { - final Routine _workoutPlan; + final Routine _routine; - const WorkoutLogs(this._workoutPlan); + const WorkoutLogs(this._routine); @override _WorkoutLogsState createState() => _WorkoutLogsState(); @@ -72,7 +72,7 @@ class _WorkoutLogsState extends State<WorkoutLogs> { ), SizedBox( width: double.infinity, - child: WorkoutLogCalendar(widget._workoutPlan), + child: WorkoutLogCalendar(widget._routine), ), ], ); @@ -89,9 +89,9 @@ class WorkoutLogEvent { } class WorkoutLogCalendar extends StatefulWidget { - final Routine _workoutPlan; + final Routine _routine; - const WorkoutLogCalendar(this._workoutPlan); + const WorkoutLogCalendar(this._routine); @override _WorkoutLogCalendarState createState() => _WorkoutLogCalendarState(); @@ -120,8 +120,8 @@ class _WorkoutLogCalendarState extends State<WorkoutLogCalendar> { } void loadEvents() { - for (final date in widget._workoutPlan.logData.keys) { - final entry = widget._workoutPlan.logData[date]!; + for (final date in widget._routine.logData.keys) { + final entry = widget._routine.logData[date]!; _events[DateFormatLists.format(date)] = [ WorkoutLogEvent(date, entry['session'], entry['exercises']), ]; @@ -179,6 +179,7 @@ class _WorkoutLogCalendarState extends State<WorkoutLogCalendar> { logEvents.first.dateTime, logEvents.first.exercises, logEvents.first.session, + widget._routine, ) : Container(); }, diff --git a/test/core/settings_test.mocks.dart b/test/core/settings_test.mocks.dart index 07d9fc3a..7a90604f 100644 --- a/test/core/settings_test.mocks.dart +++ b/test/core/settings_test.mocks.dart @@ -392,6 +392,13 @@ class MockExercisesProvider extends _i1.Mock implements _i17.ExercisesProvider { returnValueForMissingStub: _i18.Future<void>.value(), ) as _i18.Future<void>); + @override + _i18.Future<void> updateExerciseCache(_i3.ExerciseDatabase? database) => (super.noSuchMethod( + Invocation.method(#updateExerciseCache, [database]), + returnValue: _i18.Future<void>.value(), + returnValueForMissingStub: _i18.Future<void>.value(), + ) as _i18.Future<void>); + @override _i18.Future<void> fetchAndSetMuscles(_i3.ExerciseDatabase? database) => (super.noSuchMethod( Invocation.method(#fetchAndSetMuscles, [database]), diff --git a/test/workout/day_form_test.mocks.dart b/test/workout/day_form_test.mocks.dart index 8b2078ba..9568e477 100644 --- a/test/workout/day_form_test.mocks.dart +++ b/test/workout/day_form_test.mocks.dart @@ -4,11 +4,10 @@ // ignore_for_file: no_leading_underscores_for_library_prefixes import 'dart:async' as _i13; -import 'dart:ui' as _i17; +import 'dart:ui' as _i16; import 'package:mockito/mockito.dart' as _i1; -import 'package:mockito/src/dummies.dart' as _i16; -import 'package:wger/models/exercises/exercise.dart' as _i15; +import 'package:mockito/src/dummies.dart' as _i15; import 'package:wger/models/workouts/base_config.dart' as _i9; import 'package:wger/models/workouts/day.dart' as _i6; import 'package:wger/models/workouts/day_data.dart' as _i14; @@ -257,18 +256,6 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider { returnValueForMissingStub: _i13.Future<void>.value(), ) as _i13.Future<void>); - @override - _i13.Future<Map<String, dynamic>> fetchLogData( - _i5.Routine? workout, - _i15.Exercise? base, - ) => - (super.noSuchMethod( - Invocation.method(#fetchLogData, [workout, base]), - returnValue: _i13.Future<Map<String, dynamic>>.value( - <String, dynamic>{}, - ), - ) as _i13.Future<Map<String, dynamic>>); - @override _i13.Future<void> fetchAndSetRepetitionUnits() => (super.noSuchMethod( Invocation.method(#fetchAndSetRepetitionUnits, []), @@ -376,7 +363,7 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider { @override String getConfigUrl(_i8.ConfigType? type) => (super.noSuchMethod( Invocation.method(#getConfigUrl, [type]), - returnValue: _i16.dummyValue<String>( + returnValue: _i15.dummyValue<String>( this, Invocation.method(#getConfigUrl, [type]), ), @@ -464,13 +451,13 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider { ) as _i13.Future<void>); @override - void addListener(_i17.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i16.VoidCallback? listener) => super.noSuchMethod( Invocation.method(#addListener, [listener]), returnValueForMissingStub: null, ); @override - void removeListener(_i17.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i16.VoidCallback? listener) => super.noSuchMethod( Invocation.method(#removeListener, [listener]), returnValueForMissingStub: null, ); diff --git a/test/workout/gym_mode_screen_test.mocks.dart b/test/workout/gym_mode_screen_test.mocks.dart index a17dabbf..f19ff3b5 100644 --- a/test/workout/gym_mode_screen_test.mocks.dart +++ b/test/workout/gym_mode_screen_test.mocks.dart @@ -464,6 +464,13 @@ class MockExercisesProvider extends _i1.Mock implements _i12.ExercisesProvider { returnValueForMissingStub: _i11.Future<void>.value(), ) as _i11.Future<void>); + @override + _i11.Future<void> updateExerciseCache(_i5.ExerciseDatabase? database) => (super.noSuchMethod( + Invocation.method(#updateExerciseCache, [database]), + returnValue: _i11.Future<void>.value(), + returnValueForMissingStub: _i11.Future<void>.value(), + ) as _i11.Future<void>); + @override _i11.Future<void> fetchAndSetMuscles(_i5.ExerciseDatabase? database) => (super.noSuchMethod( Invocation.method(#fetchAndSetMuscles, [database]), diff --git a/test/workout/repetition_unit_form_widget_test.mocks.dart b/test/workout/repetition_unit_form_widget_test.mocks.dart index 95b4a18c..cea8ae43 100644 --- a/test/workout/repetition_unit_form_widget_test.mocks.dart +++ b/test/workout/repetition_unit_form_widget_test.mocks.dart @@ -4,11 +4,10 @@ // ignore_for_file: no_leading_underscores_for_library_prefixes import 'dart:async' as _i13; -import 'dart:ui' as _i17; +import 'dart:ui' as _i16; import 'package:mockito/mockito.dart' as _i1; -import 'package:mockito/src/dummies.dart' as _i16; -import 'package:wger/models/exercises/exercise.dart' as _i15; +import 'package:mockito/src/dummies.dart' as _i15; import 'package:wger/models/workouts/base_config.dart' as _i9; import 'package:wger/models/workouts/day.dart' as _i6; import 'package:wger/models/workouts/day_data.dart' as _i14; @@ -257,18 +256,6 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider { returnValueForMissingStub: _i13.Future<void>.value(), ) as _i13.Future<void>); - @override - _i13.Future<Map<String, dynamic>> fetchLogData( - _i5.Routine? workout, - _i15.Exercise? base, - ) => - (super.noSuchMethod( - Invocation.method(#fetchLogData, [workout, base]), - returnValue: _i13.Future<Map<String, dynamic>>.value( - <String, dynamic>{}, - ), - ) as _i13.Future<Map<String, dynamic>>); - @override _i13.Future<void> fetchAndSetRepetitionUnits() => (super.noSuchMethod( Invocation.method(#fetchAndSetRepetitionUnits, []), @@ -376,7 +363,7 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider { @override String getConfigUrl(_i8.ConfigType? type) => (super.noSuchMethod( Invocation.method(#getConfigUrl, [type]), - returnValue: _i16.dummyValue<String>( + returnValue: _i15.dummyValue<String>( this, Invocation.method(#getConfigUrl, [type]), ), @@ -464,13 +451,13 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider { ) as _i13.Future<void>); @override - void addListener(_i17.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i16.VoidCallback? listener) => super.noSuchMethod( Invocation.method(#addListener, [listener]), returnValueForMissingStub: null, ); @override - void removeListener(_i17.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i16.VoidCallback? listener) => super.noSuchMethod( Invocation.method(#removeListener, [listener]), returnValueForMissingStub: null, ); diff --git a/test/workout/routine_edit_screen_test.mocks.dart b/test/workout/routine_edit_screen_test.mocks.dart index bcccb3aa..e80671ea 100644 --- a/test/workout/routine_edit_screen_test.mocks.dart +++ b/test/workout/routine_edit_screen_test.mocks.dart @@ -4,11 +4,10 @@ // ignore_for_file: no_leading_underscores_for_library_prefixes import 'dart:async' as _i13; -import 'dart:ui' as _i17; +import 'dart:ui' as _i16; import 'package:mockito/mockito.dart' as _i1; -import 'package:mockito/src/dummies.dart' as _i16; -import 'package:wger/models/exercises/exercise.dart' as _i15; +import 'package:mockito/src/dummies.dart' as _i15; import 'package:wger/models/workouts/base_config.dart' as _i9; import 'package:wger/models/workouts/day.dart' as _i6; import 'package:wger/models/workouts/day_data.dart' as _i14; @@ -257,18 +256,6 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider { returnValueForMissingStub: _i13.Future<void>.value(), ) as _i13.Future<void>); - @override - _i13.Future<Map<String, dynamic>> fetchLogData( - _i5.Routine? workout, - _i15.Exercise? base, - ) => - (super.noSuchMethod( - Invocation.method(#fetchLogData, [workout, base]), - returnValue: _i13.Future<Map<String, dynamic>>.value( - <String, dynamic>{}, - ), - ) as _i13.Future<Map<String, dynamic>>); - @override _i13.Future<void> fetchAndSetRepetitionUnits() => (super.noSuchMethod( Invocation.method(#fetchAndSetRepetitionUnits, []), @@ -376,7 +363,7 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider { @override String getConfigUrl(_i8.ConfigType? type) => (super.noSuchMethod( Invocation.method(#getConfigUrl, [type]), - returnValue: _i16.dummyValue<String>( + returnValue: _i15.dummyValue<String>( this, Invocation.method(#getConfigUrl, [type]), ), @@ -464,13 +451,13 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider { ) as _i13.Future<void>); @override - void addListener(_i17.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i16.VoidCallback? listener) => super.noSuchMethod( Invocation.method(#addListener, [listener]), returnValueForMissingStub: null, ); @override - void removeListener(_i17.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i16.VoidCallback? listener) => super.noSuchMethod( Invocation.method(#removeListener, [listener]), returnValueForMissingStub: null, ); diff --git a/test/workout/routine_edit_test.mocks.dart b/test/workout/routine_edit_test.mocks.dart index 53590528..e23a10c7 100644 --- a/test/workout/routine_edit_test.mocks.dart +++ b/test/workout/routine_edit_test.mocks.dart @@ -4,11 +4,10 @@ // ignore_for_file: no_leading_underscores_for_library_prefixes import 'dart:async' as _i13; -import 'dart:ui' as _i17; +import 'dart:ui' as _i16; import 'package:mockito/mockito.dart' as _i1; -import 'package:mockito/src/dummies.dart' as _i16; -import 'package:wger/models/exercises/exercise.dart' as _i15; +import 'package:mockito/src/dummies.dart' as _i15; import 'package:wger/models/workouts/base_config.dart' as _i9; import 'package:wger/models/workouts/day.dart' as _i6; import 'package:wger/models/workouts/day_data.dart' as _i14; @@ -257,18 +256,6 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider { returnValueForMissingStub: _i13.Future<void>.value(), ) as _i13.Future<void>); - @override - _i13.Future<Map<String, dynamic>> fetchLogData( - _i5.Routine? workout, - _i15.Exercise? base, - ) => - (super.noSuchMethod( - Invocation.method(#fetchLogData, [workout, base]), - returnValue: _i13.Future<Map<String, dynamic>>.value( - <String, dynamic>{}, - ), - ) as _i13.Future<Map<String, dynamic>>); - @override _i13.Future<void> fetchAndSetRepetitionUnits() => (super.noSuchMethod( Invocation.method(#fetchAndSetRepetitionUnits, []), @@ -376,7 +363,7 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider { @override String getConfigUrl(_i8.ConfigType? type) => (super.noSuchMethod( Invocation.method(#getConfigUrl, [type]), - returnValue: _i16.dummyValue<String>( + returnValue: _i15.dummyValue<String>( this, Invocation.method(#getConfigUrl, [type]), ), @@ -464,13 +451,13 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider { ) as _i13.Future<void>); @override - void addListener(_i17.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i16.VoidCallback? listener) => super.noSuchMethod( Invocation.method(#addListener, [listener]), returnValueForMissingStub: null, ); @override - void removeListener(_i17.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i16.VoidCallback? listener) => super.noSuchMethod( Invocation.method(#removeListener, [listener]), returnValueForMissingStub: null, ); diff --git a/test/workout/routine_form_test.mocks.dart b/test/workout/routine_form_test.mocks.dart index 225f0fe7..db77f4a4 100644 --- a/test/workout/routine_form_test.mocks.dart +++ b/test/workout/routine_form_test.mocks.dart @@ -4,11 +4,10 @@ // ignore_for_file: no_leading_underscores_for_library_prefixes import 'dart:async' as _i13; -import 'dart:ui' as _i17; +import 'dart:ui' as _i16; import 'package:mockito/mockito.dart' as _i1; -import 'package:mockito/src/dummies.dart' as _i16; -import 'package:wger/models/exercises/exercise.dart' as _i15; +import 'package:mockito/src/dummies.dart' as _i15; import 'package:wger/models/workouts/base_config.dart' as _i9; import 'package:wger/models/workouts/day.dart' as _i6; import 'package:wger/models/workouts/day_data.dart' as _i14; @@ -257,18 +256,6 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider { returnValueForMissingStub: _i13.Future<void>.value(), ) as _i13.Future<void>); - @override - _i13.Future<Map<String, dynamic>> fetchLogData( - _i5.Routine? workout, - _i15.Exercise? base, - ) => - (super.noSuchMethod( - Invocation.method(#fetchLogData, [workout, base]), - returnValue: _i13.Future<Map<String, dynamic>>.value( - <String, dynamic>{}, - ), - ) as _i13.Future<Map<String, dynamic>>); - @override _i13.Future<void> fetchAndSetRepetitionUnits() => (super.noSuchMethod( Invocation.method(#fetchAndSetRepetitionUnits, []), @@ -376,7 +363,7 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider { @override String getConfigUrl(_i8.ConfigType? type) => (super.noSuchMethod( Invocation.method(#getConfigUrl, [type]), - returnValue: _i16.dummyValue<String>( + returnValue: _i15.dummyValue<String>( this, Invocation.method(#getConfigUrl, [type]), ), @@ -464,13 +451,13 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider { ) as _i13.Future<void>); @override - void addListener(_i17.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i16.VoidCallback? listener) => super.noSuchMethod( Invocation.method(#addListener, [listener]), returnValueForMissingStub: null, ); @override - void removeListener(_i17.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i16.VoidCallback? listener) => super.noSuchMethod( Invocation.method(#removeListener, [listener]), returnValueForMissingStub: null, ); diff --git a/test/workout/routine_logs_screen_test.dart b/test/workout/routine_logs_screen_test.dart index ad8cda1d..d7fc5640 100644 --- a/test/workout/routine_logs_screen_test.dart +++ b/test/workout/routine_logs_screen_test.dart @@ -16,6 +16,8 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +import 'dart:io'; + import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -71,7 +73,7 @@ void main() { await tester.tap(find.byType(TextButton)); await tester.pumpAndSettle(); - await screenMatchesGolden(tester, 'routine_logs_screen_detail'); + await screenMatchesGolden(tester, 'routine_logs_screen_detail', skip: !Platform.isLinux); // expect(find.text('3 day workout'), findsOneWidget); diff --git a/test/workout/routine_logs_screen_test.mocks.dart b/test/workout/routine_logs_screen_test.mocks.dart index 943b73df..721d7844 100644 --- a/test/workout/routine_logs_screen_test.mocks.dart +++ b/test/workout/routine_logs_screen_test.mocks.dart @@ -4,11 +4,10 @@ // ignore_for_file: no_leading_underscores_for_library_prefixes import 'dart:async' as _i13; -import 'dart:ui' as _i17; +import 'dart:ui' as _i16; import 'package:mockito/mockito.dart' as _i1; -import 'package:mockito/src/dummies.dart' as _i16; -import 'package:wger/models/exercises/exercise.dart' as _i15; +import 'package:mockito/src/dummies.dart' as _i15; import 'package:wger/models/workouts/base_config.dart' as _i9; import 'package:wger/models/workouts/day.dart' as _i6; import 'package:wger/models/workouts/day_data.dart' as _i14; @@ -257,18 +256,6 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider { returnValueForMissingStub: _i13.Future<void>.value(), ) as _i13.Future<void>); - @override - _i13.Future<Map<String, dynamic>> fetchLogData( - _i5.Routine? workout, - _i15.Exercise? base, - ) => - (super.noSuchMethod( - Invocation.method(#fetchLogData, [workout, base]), - returnValue: _i13.Future<Map<String, dynamic>>.value( - <String, dynamic>{}, - ), - ) as _i13.Future<Map<String, dynamic>>); - @override _i13.Future<void> fetchAndSetRepetitionUnits() => (super.noSuchMethod( Invocation.method(#fetchAndSetRepetitionUnits, []), @@ -376,7 +363,7 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider { @override String getConfigUrl(_i8.ConfigType? type) => (super.noSuchMethod( Invocation.method(#getConfigUrl, [type]), - returnValue: _i16.dummyValue<String>( + returnValue: _i15.dummyValue<String>( this, Invocation.method(#getConfigUrl, [type]), ), @@ -464,13 +451,13 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider { ) as _i13.Future<void>); @override - void addListener(_i17.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i16.VoidCallback? listener) => super.noSuchMethod( Invocation.method(#addListener, [listener]), returnValueForMissingStub: null, ); @override - void removeListener(_i17.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i16.VoidCallback? listener) => super.noSuchMethod( Invocation.method(#removeListener, [listener]), returnValueForMissingStub: null, ); diff --git a/test/workout/routine_model_test.dart b/test/workout/routine_model_test.dart index b6b5e64e..2ec646a0 100644 --- a/test/workout/routine_model_test.dart +++ b/test/workout/routine_model_test.dart @@ -18,7 +18,6 @@ import 'package:flutter_test/flutter_test.dart'; -import '../../test_data/exercises.dart'; import '../../test_data/routines.dart'; void main() { @@ -27,16 +26,27 @@ void main() { final routine = getTestRoutine(); expect(routine.logs.length, 3); - final logExercise1 = routine.filterLogsByExercise(getTestExercises()[0]); + final logExercise1 = routine.filterLogsByExercise(1); expect(logExercise1.length, 2); expect(logExercise1[0].id, 1); expect(logExercise1[1].id, 2); - final logExercise2 = routine.filterLogsByExercise(getTestExercises()[1]); + final logExercise2 = routine.filterLogsByExercise(2); expect(logExercise2.length, 1); expect(logExercise2[0].id, 3); - expect(routine.filterLogsByExercise(getTestExercises()[2]).length, 0); + expect(routine.filterLogsByExercise(3).length, 0); + }); + + test('Test the groupLogsByRepetition method', () { + final routine = getTestRoutine(); + + expect(routine.logs.length, 3); + final result = routine.groupLogsByRepetition(); + expect(result.keys, [10, 12, 8]); + expect(result[8], [routine.logs[2]]); + expect(result[10], [routine.logs[0]]); + expect(result[12], [routine.logs[1]]); }); }); } diff --git a/test/workout/slot_entry_form_test.mocks.dart b/test/workout/slot_entry_form_test.mocks.dart index 78ac108c..d882bee3 100644 --- a/test/workout/slot_entry_form_test.mocks.dart +++ b/test/workout/slot_entry_form_test.mocks.dart @@ -4,11 +4,10 @@ // ignore_for_file: no_leading_underscores_for_library_prefixes import 'dart:async' as _i13; -import 'dart:ui' as _i17; +import 'dart:ui' as _i16; import 'package:mockito/mockito.dart' as _i1; -import 'package:mockito/src/dummies.dart' as _i16; -import 'package:wger/models/exercises/exercise.dart' as _i15; +import 'package:mockito/src/dummies.dart' as _i15; import 'package:wger/models/workouts/base_config.dart' as _i9; import 'package:wger/models/workouts/day.dart' as _i6; import 'package:wger/models/workouts/day_data.dart' as _i14; @@ -257,18 +256,6 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider { returnValueForMissingStub: _i13.Future<void>.value(), ) as _i13.Future<void>); - @override - _i13.Future<Map<String, dynamic>> fetchLogData( - _i5.Routine? workout, - _i15.Exercise? base, - ) => - (super.noSuchMethod( - Invocation.method(#fetchLogData, [workout, base]), - returnValue: _i13.Future<Map<String, dynamic>>.value( - <String, dynamic>{}, - ), - ) as _i13.Future<Map<String, dynamic>>); - @override _i13.Future<void> fetchAndSetRepetitionUnits() => (super.noSuchMethod( Invocation.method(#fetchAndSetRepetitionUnits, []), @@ -376,7 +363,7 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider { @override String getConfigUrl(_i8.ConfigType? type) => (super.noSuchMethod( Invocation.method(#getConfigUrl, [type]), - returnValue: _i16.dummyValue<String>( + returnValue: _i15.dummyValue<String>( this, Invocation.method(#getConfigUrl, [type]), ), @@ -464,13 +451,13 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider { ) as _i13.Future<void>); @override - void addListener(_i17.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i16.VoidCallback? listener) => super.noSuchMethod( Invocation.method(#addListener, [listener]), returnValueForMissingStub: null, ); @override - void removeListener(_i17.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i16.VoidCallback? listener) => super.noSuchMethod( Invocation.method(#removeListener, [listener]), returnValueForMissingStub: null, ); diff --git a/test/workout/weight_unit_form_widget_test.mocks.dart b/test/workout/weight_unit_form_widget_test.mocks.dart index 16877e0d..d08b8278 100644 --- a/test/workout/weight_unit_form_widget_test.mocks.dart +++ b/test/workout/weight_unit_form_widget_test.mocks.dart @@ -4,11 +4,10 @@ // ignore_for_file: no_leading_underscores_for_library_prefixes import 'dart:async' as _i13; -import 'dart:ui' as _i17; +import 'dart:ui' as _i16; import 'package:mockito/mockito.dart' as _i1; -import 'package:mockito/src/dummies.dart' as _i16; -import 'package:wger/models/exercises/exercise.dart' as _i15; +import 'package:mockito/src/dummies.dart' as _i15; import 'package:wger/models/workouts/base_config.dart' as _i9; import 'package:wger/models/workouts/day.dart' as _i6; import 'package:wger/models/workouts/day_data.dart' as _i14; @@ -257,18 +256,6 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider { returnValueForMissingStub: _i13.Future<void>.value(), ) as _i13.Future<void>); - @override - _i13.Future<Map<String, dynamic>> fetchLogData( - _i5.Routine? workout, - _i15.Exercise? base, - ) => - (super.noSuchMethod( - Invocation.method(#fetchLogData, [workout, base]), - returnValue: _i13.Future<Map<String, dynamic>>.value( - <String, dynamic>{}, - ), - ) as _i13.Future<Map<String, dynamic>>); - @override _i13.Future<void> fetchAndSetRepetitionUnits() => (super.noSuchMethod( Invocation.method(#fetchAndSetRepetitionUnits, []), @@ -376,7 +363,7 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider { @override String getConfigUrl(_i8.ConfigType? type) => (super.noSuchMethod( Invocation.method(#getConfigUrl, [type]), - returnValue: _i16.dummyValue<String>( + returnValue: _i15.dummyValue<String>( this, Invocation.method(#getConfigUrl, [type]), ), @@ -464,13 +451,13 @@ class MockRoutinesProvider extends _i1.Mock implements _i12.RoutinesProvider { ) as _i13.Future<void>); @override - void addListener(_i17.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i16.VoidCallback? listener) => super.noSuchMethod( Invocation.method(#addListener, [listener]), returnValueForMissingStub: null, ); @override - void removeListener(_i17.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i16.VoidCallback? listener) => super.noSuchMethod( Invocation.method(#removeListener, [listener]), returnValueForMissingStub: null, );