mirror of
https://github.com/wger-project/flutter.git
synced 2026-02-18 00:17:48 +01:00
Override the equals operator for workout plan logs
Two logs are considered equal if their content is equal. This is used e.g. in the gym mode where we want to have unique values
This commit is contained in:
@@ -16,6 +16,8 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:wger/helpers/json.dart';
|
||||
import 'package:wger/helpers/misc.dart';
|
||||
@@ -107,4 +109,29 @@ class Log {
|
||||
String get singleLogRepText {
|
||||
return repText(reps, repetitionUnitObj, weight, weightUnitObj, rir);
|
||||
}
|
||||
|
||||
/// Override the equals operator
|
||||
///
|
||||
/// Two logs are considered equal if their content is equal. This is used e.g.
|
||||
/// in lists where we want to have unique values
|
||||
bool operator ==(o) {
|
||||
return o is Log &&
|
||||
exerciseId == o.exerciseId &&
|
||||
weight == o.weight &&
|
||||
weightUnitId == o.weightUnitId &&
|
||||
reps == o.reps &&
|
||||
repetitionUnitId == o.repetitionUnitId &&
|
||||
rir == o.rir;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => hashValues(exerciseId, weight, weightUnitId, reps, repetitionUnitId, rir);
|
||||
|
||||
//@override
|
||||
//int get hashCode => super.hashCode;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Log(id: $id, ex: $exerciseId, weightU: $weightUnitId, w: $weight, repU: $repetitionUnitId, rep: $reps, rir: $rir)';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,8 +69,18 @@ class WorkoutPlan {
|
||||
Map<String, dynamic> toJson() => _$WorkoutPlanToJson(this);
|
||||
|
||||
/// Filters the workout logs by exercise and sorts them by date
|
||||
List<Log> filterLogsByExercise(Exercise exercise) {
|
||||
///
|
||||
/// Optionally, filters list so that only unique logs are returned. "Unique"
|
||||
/// 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();
|
||||
|
||||
if (unique) {
|
||||
out = out.toSet().toList();
|
||||
}
|
||||
|
||||
out.sort((a, b) => b.date.compareTo(a.date));
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -361,17 +361,21 @@ class _LogPageState extends State<LogPage> {
|
||||
? ListView(
|
||||
children: [
|
||||
Text(
|
||||
'Logs',
|
||||
AppLocalizations.of(context)!.labelWorkoutLogs,
|
||||
style: Theme.of(context).textTheme.headline6,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
...widget._workoutPlan.filterLogsByExercise(widget._exercise).map((log) {
|
||||
...widget._workoutPlan
|
||||
.filterLogsByExercise(widget._exercise, unique: true)
|
||||
.map((log) {
|
||||
return ListTile(
|
||||
//title: Text(log.id.toString()),
|
||||
title: Text(log.singleLogRepText.replaceAll('\n', '')),
|
||||
subtitle: Text(
|
||||
DateFormat.yMd(Localizations.localeOf(context).languageCode)
|
||||
.format(log.date)),
|
||||
trailing: Icon(Icons.arrow_forward),
|
||||
|
||||
trailing: Icon(Icons.copy),
|
||||
onTap: () {
|
||||
setState(() {
|
||||
// Text field
|
||||
|
||||
@@ -165,9 +165,9 @@ void main() {
|
||||
expect(find.text('Workout session'), findsOneWidget);
|
||||
expect(find.byType(SessionPage), findsOneWidget);
|
||||
expect(find.byType(Form), findsOneWidget);
|
||||
expect(find.byIcon(Icons.sentiment_dissatisfied), findsOneWidget);
|
||||
expect(find.byIcon(Icons.sentiment_very_dissatisfied), findsOneWidget);
|
||||
expect(find.byIcon(Icons.sentiment_neutral), findsOneWidget);
|
||||
expect(find.byIcon(Icons.sentiment_satisfied), findsOneWidget);
|
||||
expect(find.byIcon(Icons.sentiment_very_satisfied), findsOneWidget);
|
||||
expect(find.byIcon(Icons.chevron_left), findsOneWidget);
|
||||
expect(find.byIcon(Icons.close), findsOneWidget);
|
||||
expect(find.byIcon(Icons.chevron_right), findsNothing);
|
||||
|
||||
@@ -39,57 +39,68 @@ class _FakeResponse extends _i1.Fake implements _i8.Response {}
|
||||
/// A class which mocks [NutritionPlansProvider].
|
||||
///
|
||||
/// See the documentation for Mockito's code generation for more information.
|
||||
class MockNutritionPlansProvider extends _i1.Mock implements _i9.NutritionPlansProvider {
|
||||
class MockNutritionPlansProvider extends _i1.Mock
|
||||
implements _i9.NutritionPlansProvider {
|
||||
MockNutritionPlansProvider() {
|
||||
_i1.throwOnMissingStub(this);
|
||||
}
|
||||
|
||||
@override
|
||||
List<_i4.NutritionalPlan> get items =>
|
||||
(super.noSuchMethod(Invocation.getter(#items), returnValue: <_i4.NutritionalPlan>[])
|
||||
as List<_i4.NutritionalPlan>);
|
||||
(super.noSuchMethod(Invocation.getter(#items),
|
||||
returnValue: <_i4.NutritionalPlan>[]) as List<_i4.NutritionalPlan>);
|
||||
@override
|
||||
bool get hasListeners =>
|
||||
(super.noSuchMethod(Invocation.getter(#hasListeners), returnValue: false) as bool);
|
||||
(super.noSuchMethod(Invocation.getter(#hasListeners), returnValue: false)
|
||||
as bool);
|
||||
@override
|
||||
_i2.AuthProvider get auth =>
|
||||
(super.noSuchMethod(Invocation.getter(#auth), returnValue: _FakeAuthProvider())
|
||||
as _i2.AuthProvider);
|
||||
_i2.AuthProvider get auth => (super.noSuchMethod(Invocation.getter(#auth),
|
||||
returnValue: _FakeAuthProvider()) as _i2.AuthProvider);
|
||||
@override
|
||||
set auth(_i2.AuthProvider? _auth) =>
|
||||
super.noSuchMethod(Invocation.setter(#auth, _auth), returnValueForMissingStub: null);
|
||||
super.noSuchMethod(Invocation.setter(#auth, _auth),
|
||||
returnValueForMissingStub: null);
|
||||
@override
|
||||
_i3.Client get client =>
|
||||
(super.noSuchMethod(Invocation.getter(#client), returnValue: _FakeClient()) as _i3.Client);
|
||||
_i3.Client get client => (super.noSuchMethod(Invocation.getter(#client),
|
||||
returnValue: _FakeClient()) as _i3.Client);
|
||||
@override
|
||||
set client(_i3.Client? _client) =>
|
||||
super.noSuchMethod(Invocation.setter(#client, _client), returnValueForMissingStub: null);
|
||||
super.noSuchMethod(Invocation.setter(#client, _client),
|
||||
returnValueForMissingStub: null);
|
||||
@override
|
||||
_i4.NutritionalPlan findById(int? id) =>
|
||||
(super.noSuchMethod(Invocation.method(#findById, [id]), returnValue: _FakeNutritionalPlan())
|
||||
as _i4.NutritionalPlan);
|
||||
(super.noSuchMethod(Invocation.method(#findById, [id]),
|
||||
returnValue: _FakeNutritionalPlan()) as _i4.NutritionalPlan);
|
||||
@override
|
||||
_i5.Meal? findMealById(int? id) =>
|
||||
(super.noSuchMethod(Invocation.method(#findMealById, [id])) as _i5.Meal?);
|
||||
@override
|
||||
_i10.Future<void> fetchAndSetAllPlansSparse() =>
|
||||
(super.noSuchMethod(Invocation.method(#fetchAndSetAllPlansSparse, []),
|
||||
returnValue: Future<void>.value(null),
|
||||
returnValueForMissingStub: Future.value()) as _i10.Future<void>);
|
||||
@override
|
||||
_i10.Future<void> fetchAndSetAllPlansFull() =>
|
||||
(super.noSuchMethod(Invocation.method(#fetchAndSetAllPlans, []),
|
||||
(super.noSuchMethod(Invocation.method(#fetchAndSetAllPlansFull, []),
|
||||
returnValue: Future<void>.value(null),
|
||||
returnValueForMissingStub: Future.value()) as _i10.Future<void>);
|
||||
@override
|
||||
_i10.Future<_i4.NutritionalPlan> fetchAndSetPlanSparse(int? planId) =>
|
||||
(super.noSuchMethod(Invocation.method(#fetchAndSetPlanSparse, [planId]),
|
||||
returnValue: Future<_i4.NutritionalPlan>.value(_FakeNutritionalPlan()))
|
||||
returnValue:
|
||||
Future<_i4.NutritionalPlan>.value(_FakeNutritionalPlan()))
|
||||
as _i10.Future<_i4.NutritionalPlan>);
|
||||
@override
|
||||
_i10.Future<_i4.NutritionalPlan> fetchAndSetPlanFull(int? planId) =>
|
||||
(super.noSuchMethod(Invocation.method(#fetchAndSetPlan, [planId]),
|
||||
returnValue: Future<_i4.NutritionalPlan>.value(_FakeNutritionalPlan()))
|
||||
(super.noSuchMethod(Invocation.method(#fetchAndSetPlanFull, [planId]),
|
||||
returnValue:
|
||||
Future<_i4.NutritionalPlan>.value(_FakeNutritionalPlan()))
|
||||
as _i10.Future<_i4.NutritionalPlan>);
|
||||
@override
|
||||
_i10.Future<_i4.NutritionalPlan> addPlan(_i4.NutritionalPlan? planData) =>
|
||||
(super.noSuchMethod(Invocation.method(#addPlan, [planData]),
|
||||
returnValue: Future<_i4.NutritionalPlan>.value(_FakeNutritionalPlan()))
|
||||
returnValue:
|
||||
Future<_i4.NutritionalPlan>.value(_FakeNutritionalPlan()))
|
||||
as _i10.Future<_i4.NutritionalPlan>);
|
||||
@override
|
||||
_i10.Future<void> editPlan(_i4.NutritionalPlan? plan) =>
|
||||
@@ -97,93 +108,105 @@ class MockNutritionPlansProvider extends _i1.Mock implements _i9.NutritionPlansP
|
||||
returnValue: Future<void>.value(null),
|
||||
returnValueForMissingStub: Future.value()) as _i10.Future<void>);
|
||||
@override
|
||||
_i10.Future<void> deletePlan(int? id) => (super.noSuchMethod(Invocation.method(#deletePlan, [id]),
|
||||
returnValue: Future<void>.value(null),
|
||||
returnValueForMissingStub: Future.value()) as _i10.Future<void>);
|
||||
_i10.Future<void> deletePlan(int? id) =>
|
||||
(super.noSuchMethod(Invocation.method(#deletePlan, [id]),
|
||||
returnValue: Future<void>.value(null),
|
||||
returnValueForMissingStub: Future.value()) as _i10.Future<void>);
|
||||
@override
|
||||
_i10.Future<_i5.Meal> addMeal(_i5.Meal? meal, int? planId) =>
|
||||
(super.noSuchMethod(Invocation.method(#addMeal, [meal, planId]),
|
||||
returnValue: Future<_i5.Meal>.value(_FakeMeal())) as _i10.Future<_i5.Meal>);
|
||||
returnValue: Future<_i5.Meal>.value(_FakeMeal()))
|
||||
as _i10.Future<_i5.Meal>);
|
||||
@override
|
||||
_i10.Future<_i5.Meal> editMeal(_i5.Meal? meal) =>
|
||||
(super.noSuchMethod(Invocation.method(#editMeal, [meal]),
|
||||
returnValue: Future<_i5.Meal>.value(_FakeMeal())) as _i10.Future<_i5.Meal>);
|
||||
returnValue: Future<_i5.Meal>.value(_FakeMeal()))
|
||||
as _i10.Future<_i5.Meal>);
|
||||
@override
|
||||
_i10.Future<void> deleteMeal(_i5.Meal? meal) =>
|
||||
(super.noSuchMethod(Invocation.method(#deleteMeal, [meal]),
|
||||
returnValue: Future<void>.value(null),
|
||||
returnValueForMissingStub: Future.value()) as _i10.Future<void>);
|
||||
@override
|
||||
_i10.Future<_i6.MealItem> addMealItem(_i6.MealItem? mealItem, _i5.Meal? meal) =>
|
||||
_i10.Future<_i6.MealItem> addMealItem(
|
||||
_i6.MealItem? mealItem, _i5.Meal? meal) =>
|
||||
(super.noSuchMethod(Invocation.method(#addMealItem, [mealItem, meal]),
|
||||
returnValue: Future<_i6.MealItem>.value(_FakeMealItem())) as _i10.Future<_i6.MealItem>);
|
||||
returnValue: Future<_i6.MealItem>.value(_FakeMealItem()))
|
||||
as _i10.Future<_i6.MealItem>);
|
||||
@override
|
||||
_i10.Future<void> deleteMealItem(_i6.MealItem? mealItem) =>
|
||||
(super.noSuchMethod(Invocation.method(#deleteMealItem, [mealItem]),
|
||||
returnValue: Future<void>.value(null),
|
||||
returnValueForMissingStub: Future.value()) as _i10.Future<void>);
|
||||
@override
|
||||
_i10.Future<_i7.Ingredient> fetchIngredient(int? ingredientId) => (super.noSuchMethod(
|
||||
Invocation.method(#fetchIngredient, [ingredientId]),
|
||||
returnValue: Future<_i7.Ingredient>.value(_FakeIngredient())) as _i10.Future<_i7.Ingredient>);
|
||||
_i10.Future<_i7.Ingredient> fetchIngredient(int? ingredientId) =>
|
||||
(super.noSuchMethod(Invocation.method(#fetchIngredient, [ingredientId]),
|
||||
returnValue: Future<_i7.Ingredient>.value(_FakeIngredient()))
|
||||
as _i10.Future<_i7.Ingredient>);
|
||||
@override
|
||||
_i10.Future<void> fetchIngredientsFromCache() =>
|
||||
(super.noSuchMethod(Invocation.method(#fetchIngredientsFromCache, []),
|
||||
returnValue: Future<void>.value(null),
|
||||
returnValueForMissingStub: Future.value()) as _i10.Future<void>);
|
||||
@override
|
||||
_i10.Future<List<dynamic>> searchIngredient(String? name, [String? languageCode = r'en']) =>
|
||||
(super.noSuchMethod(Invocation.method(#searchIngredient, [name, languageCode]),
|
||||
returnValue: Future<List<dynamic>>.value(<dynamic>[])) as _i10.Future<List<dynamic>>);
|
||||
_i10.Future<List<dynamic>> searchIngredient(String? name,
|
||||
[String? languageCode = r'en']) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#searchIngredient, [name, languageCode]),
|
||||
returnValue: Future<List<dynamic>>.value(<dynamic>[]))
|
||||
as _i10.Future<List<dynamic>>);
|
||||
@override
|
||||
_i10.Future<void> logMealToDiary(_i5.Meal? meal) =>
|
||||
(super.noSuchMethod(Invocation.method(#logMealToDiary, [meal]),
|
||||
returnValue: Future<void>.value(null),
|
||||
returnValueForMissingStub: Future.value()) as _i10.Future<void>);
|
||||
@override
|
||||
_i10.Future<void> fetchAndSetAllLogs() =>
|
||||
(super.noSuchMethod(Invocation.method(#fetchAndSetAllLogs, []),
|
||||
returnValue: Future<void>.value(null),
|
||||
returnValueForMissingStub: Future.value()) as _i10.Future<void>);
|
||||
@override
|
||||
_i10.Future<void> fetchAndSetLogs(_i4.NutritionalPlan? plan) =>
|
||||
(super.noSuchMethod(Invocation.method(#fetchAndSetLogs, [plan]),
|
||||
returnValue: Future<void>.value(null),
|
||||
returnValueForMissingStub: Future.value()) as _i10.Future<void>);
|
||||
@override
|
||||
void addListener(_i11.VoidCallback? listener) => super
|
||||
.noSuchMethod(Invocation.method(#addListener, [listener]), returnValueForMissingStub: null);
|
||||
void addListener(_i11.VoidCallback? listener) =>
|
||||
super.noSuchMethod(Invocation.method(#addListener, [listener]),
|
||||
returnValueForMissingStub: null);
|
||||
@override
|
||||
void removeListener(_i11.VoidCallback? listener) =>
|
||||
super.noSuchMethod(Invocation.method(#removeListener, [listener]),
|
||||
returnValueForMissingStub: null);
|
||||
@override
|
||||
void dispose() =>
|
||||
super.noSuchMethod(Invocation.method(#dispose, []), returnValueForMissingStub: null);
|
||||
void dispose() => super.noSuchMethod(Invocation.method(#dispose, []),
|
||||
returnValueForMissingStub: null);
|
||||
@override
|
||||
void notifyListeners() =>
|
||||
super.noSuchMethod(Invocation.method(#notifyListeners, []), returnValueForMissingStub: null);
|
||||
super.noSuchMethod(Invocation.method(#notifyListeners, []),
|
||||
returnValueForMissingStub: null);
|
||||
@override
|
||||
dynamic makeUrl(String? path, {int? id, String? objectMethod, Map<String, dynamic>? query}) =>
|
||||
super.noSuchMethod(Invocation.method(
|
||||
#makeUrl, [path], {#id: id, #objectMethod: objectMethod, #query: query}));
|
||||
dynamic makeUrl(String? path,
|
||||
{int? id, String? objectMethod, Map<String, dynamic>? query}) =>
|
||||
super.noSuchMethod(Invocation.method(#makeUrl, [path],
|
||||
{#id: id, #objectMethod: objectMethod, #query: query}));
|
||||
@override
|
||||
_i10.Future<Map<String, dynamic>> fetch(Uri? uri) =>
|
||||
(super.noSuchMethod(Invocation.method(#fetch, [uri]),
|
||||
returnValue: Future<Map<String, dynamic>>.value(<String, dynamic>{}))
|
||||
as _i10.Future<Map<String, dynamic>>);
|
||||
_i10.Future<Map<String, dynamic>> fetch(Uri? uri) => (super.noSuchMethod(
|
||||
Invocation.method(#fetch, [uri]),
|
||||
returnValue: Future<Map<String, dynamic>>.value(<String, dynamic>{}))
|
||||
as _i10.Future<Map<String, dynamic>>);
|
||||
@override
|
||||
_i10.Future<Map<String, dynamic>> post(Map<String, dynamic>? data, Uri? uri) =>
|
||||
_i10.Future<Map<String, dynamic>> post(
|
||||
Map<String, dynamic>? data, Uri? uri) =>
|
||||
(super.noSuchMethod(Invocation.method(#post, [data, uri]),
|
||||
returnValue: Future<Map<String, dynamic>>.value(<String, dynamic>{}))
|
||||
returnValue:
|
||||
Future<Map<String, dynamic>>.value(<String, dynamic>{}))
|
||||
as _i10.Future<Map<String, dynamic>>);
|
||||
@override
|
||||
_i10.Future<Map<String, dynamic>> patch(Map<String, dynamic>? data, Uri? uri) =>
|
||||
_i10.Future<Map<String, dynamic>> patch(
|
||||
Map<String, dynamic>? data, Uri? uri) =>
|
||||
(super.noSuchMethod(Invocation.method(#patch, [data, uri]),
|
||||
returnValue: Future<Map<String, dynamic>>.value(<String, dynamic>{}))
|
||||
returnValue:
|
||||
Future<Map<String, dynamic>>.value(<String, dynamic>{}))
|
||||
as _i10.Future<Map<String, dynamic>>);
|
||||
@override
|
||||
_i10.Future<_i8.Response> deleteRequest(String? url, int? id) =>
|
||||
(super.noSuchMethod(Invocation.method(#deleteRequest, [url, id]),
|
||||
returnValue: Future<_i8.Response>.value(_FakeResponse())) as _i10.Future<_i8.Response>);
|
||||
returnValue: Future<_i8.Response>.value(_FakeResponse()))
|
||||
as _i10.Future<_i8.Response>);
|
||||
}
|
||||
|
||||
81
test/workout_log_model_test.dart
Normal file
81
test/workout_log_model_test.dart
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* This file is part of wger Workout Manager <https://github.com/wger-project>.
|
||||
* Copyright (C) 2020, 2021 wger Team
|
||||
*
|
||||
* wger Workout Manager is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wger Workout Manager is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:wger/models/workouts/log.dart';
|
||||
|
||||
void main() {
|
||||
group('Test the workout log model', () {
|
||||
late Log log1;
|
||||
late Log log2;
|
||||
|
||||
setUp(() {
|
||||
log1 = Log(
|
||||
id: 123,
|
||||
workoutPlan: 100,
|
||||
exerciseId: 1,
|
||||
reps: 10,
|
||||
rir: '1.5',
|
||||
repetitionUnitId: 1,
|
||||
weight: 20,
|
||||
weightUnitId: 1,
|
||||
date: DateTime(2010, 10, 1),
|
||||
);
|
||||
log2 = Log(
|
||||
id: 9,
|
||||
workoutPlan: 42,
|
||||
exerciseId: 1,
|
||||
reps: 10,
|
||||
rir: '1.5',
|
||||
repetitionUnitId: 1,
|
||||
weight: 20,
|
||||
weightUnitId: 1,
|
||||
date: DateTime(2063, 4, 5),
|
||||
);
|
||||
});
|
||||
|
||||
test('Test equal values (besides Id, workoutPlan and date)', () async {
|
||||
expect(log1, log2);
|
||||
});
|
||||
|
||||
test('Test different rir values', () async {
|
||||
log1.rir = null;
|
||||
expect(log1, isNot(log2));
|
||||
});
|
||||
|
||||
test('Test different weight values', () async {
|
||||
log1.weight = 100;
|
||||
expect(log1, isNot(log2));
|
||||
});
|
||||
|
||||
test('Test different weight units', () async {
|
||||
log1.weightUnitId = 2;
|
||||
expect(log1, isNot(log2));
|
||||
});
|
||||
|
||||
test('Test different reps', () async {
|
||||
log1.reps = 99;
|
||||
expect(log1, isNot(log2));
|
||||
});
|
||||
|
||||
test('Test different rep units', () async {
|
||||
log1.repetitionUnitId = 44;
|
||||
expect(log1, isNot(log2));
|
||||
});
|
||||
});
|
||||
}
|
||||
105
test/workout_set_form_test.dart
Normal file
105
test/workout_set_form_test.dart
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* This file is part of wger Workout Manager <https://github.com/wger-project>.
|
||||
* Copyright (C) 2020, 2021 wger Team
|
||||
*
|
||||
* wger Workout Manager is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wger Workout Manager is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter_typeahead/flutter_typeahead.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:wger/helpers/consts.dart';
|
||||
import 'package:wger/models/workouts/day.dart';
|
||||
import 'package:wger/models/workouts/set.dart';
|
||||
import 'package:wger/models/workouts/setting.dart';
|
||||
import 'package:wger/models/workouts/workout_plan.dart';
|
||||
import 'package:wger/providers/exercises.dart';
|
||||
import 'package:wger/providers/workout_plans.dart';
|
||||
import 'package:wger/widgets/workouts/forms.dart';
|
||||
|
||||
import '../test_data/workouts.dart';
|
||||
import 'base_provider_test.mocks.dart';
|
||||
import 'utils.dart';
|
||||
import 'workout_form_test.mocks.dart';
|
||||
import 'workout_set_form_test.mocks.dart';
|
||||
|
||||
@GenerateMocks([ExercisesProvider])
|
||||
void main() {
|
||||
var mockWorkoutPlans = MockWorkoutPlansProvider();
|
||||
MockExercisesProvider mockExercises = MockExercisesProvider();
|
||||
WorkoutPlan workoutPlan = getWorkout();
|
||||
final client = MockClient();
|
||||
Day day = Day();
|
||||
|
||||
setUp(() {
|
||||
WorkoutPlan workoutPlan = getWorkout();
|
||||
day = workoutPlan.days.first;
|
||||
mockWorkoutPlans = MockWorkoutPlansProvider();
|
||||
});
|
||||
|
||||
Widget createHomeScreen({locale = 'en'}) {
|
||||
return ChangeNotifierProvider<WorkoutPlansProvider>(
|
||||
create: (context) => WorkoutPlansProvider(
|
||||
testAuthProvider,
|
||||
mockExercises,
|
||||
[workoutPlan],
|
||||
client,
|
||||
),
|
||||
child: ChangeNotifierProvider(
|
||||
create: (context) => testExercisesProvider,
|
||||
child: MaterialApp(
|
||||
locale: Locale(locale),
|
||||
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
navigatorKey: GlobalKey<NavigatorState>(),
|
||||
home: Scaffold(
|
||||
body: SetFormWidget(day),
|
||||
),
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('Test the widgets on the SetFormWidget', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(createHomeScreen());
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(TypeAheadFormField), findsOneWidget);
|
||||
expect(find.byType(Slider), findsOneWidget);
|
||||
//expect(find.byType(SwitchListTile), findsOneWidget);
|
||||
expect(find.byKey(Key(SUBMIT_BUTTON_KEY_NAME)), findsOneWidget);
|
||||
expect(find.byType(ElevatedButton), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Test creating a new set', (WidgetTester tester) async {
|
||||
when(mockWorkoutPlans.addSet(any)).thenAnswer((_) => Future.value(Set.empty()));
|
||||
when(mockWorkoutPlans.addSetting(any)).thenAnswer((_) => Future.value(Setting.empty()));
|
||||
when(mockWorkoutPlans.fetchSmartText(any, any)).thenAnswer((_) => Future.value('2 x 10'));
|
||||
|
||||
await tester.pumpWidget(createHomeScreen());
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.enterText(find.byKey(Key('field-typeahead')), 'exercise');
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.tap(find.byKey(Key(SUBMIT_BUTTON_KEY_NAME)));
|
||||
|
||||
//verify(mockWorkoutPlans.addSet(any));
|
||||
//verify(mockWorkoutPlans.addSettinbg(any));
|
||||
//verify(mockWorkoutPlans.fetchSmartText(any, any));
|
||||
});
|
||||
}
|
||||
138
test/workout_set_form_test.mocks.dart
Normal file
138
test/workout_set_form_test.mocks.dart
Normal file
@@ -0,0 +1,138 @@
|
||||
// Mocks generated by Mockito 5.0.7 from annotations
|
||||
// in wger/test/workout_set_form_test.dart.
|
||||
// Do not manually edit this file.
|
||||
|
||||
import 'dart:async' as _i7;
|
||||
import 'dart:ui' as _i8;
|
||||
|
||||
import 'package:http/src/client.dart' as _i3;
|
||||
import 'package:http/src/response.dart' as _i5;
|
||||
import 'package:mockito/mockito.dart' as _i1;
|
||||
import 'package:wger/models/exercises/exercise.dart' as _i4;
|
||||
import 'package:wger/providers/auth.dart' as _i2;
|
||||
import 'package:wger/providers/exercises.dart' as _i6;
|
||||
|
||||
// ignore_for_file: comment_references
|
||||
// ignore_for_file: unnecessary_parenthesis
|
||||
|
||||
// ignore_for_file: prefer_const_constructors
|
||||
|
||||
// ignore_for_file: avoid_redundant_argument_values
|
||||
|
||||
class _FakeAuthProvider extends _i1.Fake implements _i2.AuthProvider {}
|
||||
|
||||
class _FakeClient extends _i1.Fake implements _i3.Client {}
|
||||
|
||||
class _FakeExercise extends _i1.Fake implements _i4.Exercise {}
|
||||
|
||||
class _FakeResponse extends _i1.Fake implements _i5.Response {}
|
||||
|
||||
/// A class which mocks [ExercisesProvider].
|
||||
///
|
||||
/// See the documentation for Mockito's code generation for more information.
|
||||
class MockExercisesProvider extends _i1.Mock implements _i6.ExercisesProvider {
|
||||
MockExercisesProvider() {
|
||||
_i1.throwOnMissingStub(this);
|
||||
}
|
||||
|
||||
@override
|
||||
List<_i4.Exercise> get items => (super.noSuchMethod(Invocation.getter(#items),
|
||||
returnValue: <_i4.Exercise>[]) as List<_i4.Exercise>);
|
||||
@override
|
||||
bool get hasListeners =>
|
||||
(super.noSuchMethod(Invocation.getter(#hasListeners), returnValue: false)
|
||||
as bool);
|
||||
@override
|
||||
_i2.AuthProvider get auth => (super.noSuchMethod(Invocation.getter(#auth),
|
||||
returnValue: _FakeAuthProvider()) as _i2.AuthProvider);
|
||||
@override
|
||||
set auth(_i2.AuthProvider? _auth) =>
|
||||
super.noSuchMethod(Invocation.setter(#auth, _auth),
|
||||
returnValueForMissingStub: null);
|
||||
@override
|
||||
_i3.Client get client => (super.noSuchMethod(Invocation.getter(#client),
|
||||
returnValue: _FakeClient()) as _i3.Client);
|
||||
@override
|
||||
set client(_i3.Client? _client) =>
|
||||
super.noSuchMethod(Invocation.setter(#client, _client),
|
||||
returnValueForMissingStub: null);
|
||||
@override
|
||||
_i4.Exercise findById(int? exerciseId) =>
|
||||
(super.noSuchMethod(Invocation.method(#findById, [exerciseId]),
|
||||
returnValue: _FakeExercise()) as _i4.Exercise);
|
||||
@override
|
||||
_i7.Future<void> fetchAndSetCategories() =>
|
||||
(super.noSuchMethod(Invocation.method(#fetchAndSetCategories, []),
|
||||
returnValue: Future<void>.value(null),
|
||||
returnValueForMissingStub: Future.value()) as _i7.Future<void>);
|
||||
@override
|
||||
_i7.Future<void> fetchAndSetMuscles() =>
|
||||
(super.noSuchMethod(Invocation.method(#fetchAndSetMuscles, []),
|
||||
returnValue: Future<void>.value(null),
|
||||
returnValueForMissingStub: Future.value()) as _i7.Future<void>);
|
||||
@override
|
||||
_i7.Future<void> fetchAndSetEquipment() =>
|
||||
(super.noSuchMethod(Invocation.method(#fetchAndSetEquipment, []),
|
||||
returnValue: Future<void>.value(null),
|
||||
returnValueForMissingStub: Future.value()) as _i7.Future<void>);
|
||||
@override
|
||||
_i7.Future<_i4.Exercise> fetchAndSetExercise(int? exerciseId) =>
|
||||
(super.noSuchMethod(Invocation.method(#fetchAndSetExercise, [exerciseId]),
|
||||
returnValue: Future<_i4.Exercise>.value(_FakeExercise()))
|
||||
as _i7.Future<_i4.Exercise>);
|
||||
@override
|
||||
_i7.Future<void> fetchAndSetExercises() =>
|
||||
(super.noSuchMethod(Invocation.method(#fetchAndSetExercises, []),
|
||||
returnValue: Future<void>.value(null),
|
||||
returnValueForMissingStub: Future.value()) as _i7.Future<void>);
|
||||
@override
|
||||
_i7.Future<List<dynamic>> searchExercise(String? name,
|
||||
[String? languageCode = r'en']) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#searchExercise, [name, languageCode]),
|
||||
returnValue: Future<List<dynamic>>.value(<dynamic>[]))
|
||||
as _i7.Future<List<dynamic>>);
|
||||
@override
|
||||
void addListener(_i8.VoidCallback? listener) =>
|
||||
super.noSuchMethod(Invocation.method(#addListener, [listener]),
|
||||
returnValueForMissingStub: null);
|
||||
@override
|
||||
void removeListener(_i8.VoidCallback? listener) =>
|
||||
super.noSuchMethod(Invocation.method(#removeListener, [listener]),
|
||||
returnValueForMissingStub: null);
|
||||
@override
|
||||
void dispose() => super.noSuchMethod(Invocation.method(#dispose, []),
|
||||
returnValueForMissingStub: null);
|
||||
@override
|
||||
void notifyListeners() =>
|
||||
super.noSuchMethod(Invocation.method(#notifyListeners, []),
|
||||
returnValueForMissingStub: null);
|
||||
@override
|
||||
dynamic makeUrl(String? path,
|
||||
{int? id, String? objectMethod, Map<String, dynamic>? query}) =>
|
||||
super.noSuchMethod(Invocation.method(#makeUrl, [path],
|
||||
{#id: id, #objectMethod: objectMethod, #query: query}));
|
||||
@override
|
||||
_i7.Future<Map<String, dynamic>> fetch(Uri? uri) => (super.noSuchMethod(
|
||||
Invocation.method(#fetch, [uri]),
|
||||
returnValue: Future<Map<String, dynamic>>.value(<String, dynamic>{}))
|
||||
as _i7.Future<Map<String, dynamic>>);
|
||||
@override
|
||||
_i7.Future<Map<String, dynamic>> post(Map<String, dynamic>? data, Uri? uri) =>
|
||||
(super.noSuchMethod(Invocation.method(#post, [data, uri]),
|
||||
returnValue:
|
||||
Future<Map<String, dynamic>>.value(<String, dynamic>{}))
|
||||
as _i7.Future<Map<String, dynamic>>);
|
||||
@override
|
||||
_i7.Future<Map<String, dynamic>> patch(
|
||||
Map<String, dynamic>? data, Uri? uri) =>
|
||||
(super.noSuchMethod(Invocation.method(#patch, [data, uri]),
|
||||
returnValue:
|
||||
Future<Map<String, dynamic>>.value(<String, dynamic>{}))
|
||||
as _i7.Future<Map<String, dynamic>>);
|
||||
@override
|
||||
_i7.Future<_i5.Response> deleteRequest(String? url, int? id) =>
|
||||
(super.noSuchMethod(Invocation.method(#deleteRequest, [url, id]),
|
||||
returnValue: Future<_i5.Response>.value(_FakeResponse()))
|
||||
as _i7.Future<_i5.Response>);
|
||||
}
|
||||
Reference in New Issue
Block a user