Merge branch 'testing_branch' of https://gitlab.com/Crondung/hsma_cpd into testing_branch
commit
6b02ec5a6b
|
@ -2,6 +2,7 @@ image: cirrusci/flutter:3.7.5
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- analyze
|
- analyze
|
||||||
|
- test
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- flutter pub get
|
- flutter pub get
|
||||||
|
@ -13,3 +14,10 @@ analyze:
|
||||||
- flutter analyze
|
- flutter analyze
|
||||||
only:
|
only:
|
||||||
- merge_requests
|
- merge_requests
|
||||||
|
|
||||||
|
test:
|
||||||
|
stage: test
|
||||||
|
script:
|
||||||
|
- flutter test
|
||||||
|
only:
|
||||||
|
- merge_requests
|
||||||
|
|
|
@ -1,37 +1,112 @@
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:timezone/data/latest.dart' as tz;
|
|
||||||
import 'package:smoke_cess_app/services/date_service.dart';
|
import 'package:smoke_cess_app/services/date_service.dart';
|
||||||
|
import 'package:smoke_cess_app/services/pages_service.dart';
|
||||||
|
import 'package:timezone/data/latest.dart' as tz;
|
||||||
import 'package:timezone/timezone.dart';
|
import 'package:timezone/timezone.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
tz.initializeTimeZones();
|
group('Helpers', () {
|
||||||
test('IsSameDay: false', () {
|
group('isSameDay', () {
|
||||||
bool result =
|
test('returns true when dates are the same day', () {
|
||||||
isSameDay(DateTime.now(), DateTime.now().add(const Duration(days: 1)));
|
DateTime dateA = DateTime.now();
|
||||||
expect(result, false);
|
DateTime dateB = DateTime(dateA.year, dateA.month, dateA.day, 10, 0);
|
||||||
|
expect(isSameDay(dateA, dateB), true);
|
||||||
});
|
});
|
||||||
test('IsSameDay: true', () {
|
|
||||||
bool result = isSameDay(DateTime.now(), DateTime.now());
|
test('returns false when dates are different days', () {
|
||||||
|
DateTime dateA = DateTime.now();
|
||||||
|
DateTime dateB =
|
||||||
|
DateTime(dateA.year, dateA.month, dateA.day + 1, 10, 0);
|
||||||
|
expect(isSameDay(dateA, dateB), false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('returns false when one date is null', () {
|
||||||
|
DateTime? dateA = DateTime.now();
|
||||||
|
DateTime? dateB;
|
||||||
|
expect(isSameDay(dateA, dateB), false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
group('createTZDateTimes', () {
|
||||||
|
test('returns empty list when selectedDays is null', () {
|
||||||
|
List<TZDateTime> tzDateTimes = createTZDateTimes(null, 10, 0);
|
||||||
|
expect(tzDateTimes, []);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('returns empty list when selectedHours is null', () {
|
||||||
|
List<TZDateTime> tzDateTimes = createTZDateTimes(['Montag'], null, 0);
|
||||||
|
expect(tzDateTimes, []);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('returns empty list when selectedMinutes is null', () {
|
||||||
|
List<TZDateTime> tzDateTimes = createTZDateTimes(['Montag'], 10, null);
|
||||||
|
expect(tzDateTimes, []);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('returns empty list when no valid dates are found', () {
|
||||||
|
List<TZDateTime> tzDateTimes = createTZDateTimes(['Montag'], 10, 0);
|
||||||
|
expect(tzDateTimes, []);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('returns list of valid dates', () {
|
||||||
|
List<TZDateTime> tzDateTimes = createTZDateTimes(['Montag'], 10, 0);
|
||||||
|
expect(tzDateTimes.length, greaterThan(0));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
group('getTimeTill', () {
|
||||||
|
test('returns time till next mood', () async {
|
||||||
|
Duration duration = await getTimeTill(Pages.mood);
|
||||||
|
expect(duration, isNotNull);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('returns time till next sleep', () async {
|
||||||
|
Duration duration = await getTimeTill(Pages.sleep);
|
||||||
|
expect(duration, isNotNull);
|
||||||
|
});
|
||||||
|
//?
|
||||||
|
test('returns time till next workout', () async {
|
||||||
|
Duration duration = await getTimeTill(Pages.relapse);
|
||||||
|
expect(duration, isNotNull);
|
||||||
|
});
|
||||||
|
//?
|
||||||
|
test('returns time till next workout', () async {
|
||||||
|
Duration duration = await getTimeTill(Pages.settings);
|
||||||
|
expect(duration, isNotNull);
|
||||||
|
});
|
||||||
|
test('returns time till next workout', () async {
|
||||||
|
Duration duration = await getTimeTill(Pages.timer);
|
||||||
|
expect(duration, isNotNull);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
group('Helper functions', () {
|
||||||
|
setUp(() async {
|
||||||
|
tz.initializeTimeZones();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('isSameDay returns true if two dates are the same day', () {
|
||||||
|
final date1 = DateTime(2022, 3, 6);
|
||||||
|
final date2 = DateTime(2022, 3, 6, 15, 30);
|
||||||
|
final result = isSameDay(date1, date2);
|
||||||
expect(result, true);
|
expect(result, true);
|
||||||
});
|
});
|
||||||
test('CreateTZDateTimes: all the same days as today in next 6 weeks at 23:59',
|
|
||||||
() {
|
test('isSameDay returns false if two dates are not the same day', () {
|
||||||
List<String> selectedDays = [
|
final date1 = DateTime(2022, 3, 6);
|
||||||
weekDays.keys.elementAt(DateTime.now().weekday - 1)
|
final date2 = DateTime(2022, 3, 7);
|
||||||
];
|
final result = isSameDay(date1, date2);
|
||||||
List<TZDateTime> expected = [];
|
expect(result, false);
|
||||||
DateTime now = DateTime.now();
|
});
|
||||||
final Duration offset = now.timeZoneOffset;
|
|
||||||
final DateTime date =
|
test('createTZDateTimes returns a list of TZDateTime objects', () async {
|
||||||
DateTime(now.year, now.month, now.day, 23, 59, 0, 0, 0);
|
final selectedDays = ['Montag', 'Dienstag'];
|
||||||
for (int i = 0; i <= trainingTime; i = i + 7) {
|
final selectedHours = 12;
|
||||||
expected.add(
|
final selectedMinutes = 30;
|
||||||
TZDateTime.local(date.year, date.month, date.day, 23, 59, 0, 0, 0)
|
final result =
|
||||||
.add(Duration(days: i))
|
await createTZDateTimes(selectedDays, selectedHours, selectedMinutes);
|
||||||
// subtract offset since TZDateTime uses the UTC Timezone
|
expect(result, isA<List<TZDateTime>>());
|
||||||
.subtract(offset));
|
});
|
||||||
}
|
|
||||||
List<TZDateTime> result = createTZDateTimes(selectedDays, 23, 59);
|
|
||||||
expect(result, expected);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:smoke_cess_app/providers/settings_provider.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
group('SettingsProvider', () {
|
||||||
|
test('initial state', () {
|
||||||
|
final provider = SettingsProvider();
|
||||||
|
expect(provider.settings, isNull);
|
||||||
|
expect(provider.initialized, isFalse);
|
||||||
|
expect(provider.scanning, isFalse);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('initialize settings', () async {
|
||||||
|
final provider = SettingsProvider();
|
||||||
|
provider.initSettings();
|
||||||
|
expect(provider.settings, isNotNull);
|
||||||
|
expect(provider.initialized, isTrue);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('set scanning', () {
|
||||||
|
final provider = SettingsProvider();
|
||||||
|
provider.scanning = true;
|
||||||
|
expect(provider.scanning, isTrue);
|
||||||
|
provider.scanning = false;
|
||||||
|
expect(provider.scanning, isFalse);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:smoke_cess_app/providers/audio_provider.dart';
|
||||||
|
import 'package:smoke_cess_app/providers/timer_provider.dart';
|
||||||
|
import 'package:smoke_cess_app/providers/workout_provider.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
group('WorkoutProvider', () {
|
||||||
|
late WorkoutProvider workoutProvider;
|
||||||
|
late TimerProvider timerProvider;
|
||||||
|
late AudioProvider audioProvider;
|
||||||
|
|
||||||
|
setUp(() {
|
||||||
|
timerProvider = TimerProvider();
|
||||||
|
audioProvider = AudioProvider();
|
||||||
|
workoutProvider = WorkoutProvider(timerProvider, audioProvider);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('initial values', () {
|
||||||
|
expect(workoutProvider.isWorkoutStarted, false);
|
||||||
|
expect(workoutProvider.isWorkoutComplete, false);
|
||||||
|
expect(workoutProvider.motivationBefore, 50);
|
||||||
|
expect(workoutProvider.motivationAfter, 50);
|
||||||
|
expect(workoutProvider.currentPhase, WorkoutPhases.warmUp);
|
||||||
|
expect(workoutProvider.currentPhaseDuration, const Duration(seconds: 5));
|
||||||
|
expect(workoutProvider.isPhaseComplete, false);
|
||||||
|
expect(workoutProvider.currentPhaseColor, Colors.green);
|
||||||
|
expect(workoutProvider.currentPhaseTitle, 'Warm Up');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('next phase', () {
|
||||||
|
workoutProvider.nextPhase();
|
||||||
|
|
||||||
|
expect(workoutProvider.currentPhase, WorkoutPhases.highIntensity);
|
||||||
|
expect(workoutProvider.currentPhaseDuration, const Duration(seconds: 4));
|
||||||
|
expect(workoutProvider.isPhaseComplete, false);
|
||||||
|
expect(workoutProvider.currentPhaseColor, Colors.red);
|
||||||
|
expect(workoutProvider.currentPhaseTitle, 'High Intensity');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('start workout', () {
|
||||||
|
workoutProvider.startWorkout();
|
||||||
|
|
||||||
|
expect(workoutProvider.isWorkoutStarted, true);
|
||||||
|
expect(workoutProvider.isWorkoutComplete, false);
|
||||||
|
expect(workoutProvider.currentPhase, WorkoutPhases.warmUp);
|
||||||
|
expect(workoutProvider.currentPhaseDuration, const Duration(seconds: 5));
|
||||||
|
expect(workoutProvider.isPhaseComplete, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('stop workout', () {
|
||||||
|
workoutProvider.startWorkout();
|
||||||
|
workoutProvider.stopWorkout();
|
||||||
|
|
||||||
|
expect(workoutProvider.isWorkoutStarted, false);
|
||||||
|
expect(workoutProvider.isWorkoutComplete, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('interrupt workout', () {
|
||||||
|
workoutProvider.startWorkout();
|
||||||
|
workoutProvider.interruptWorkout();
|
||||||
|
|
||||||
|
expect(workoutProvider.isWorkoutStarted, false);
|
||||||
|
expect(workoutProvider.isWorkoutComplete, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
// test('save workout', () {
|
||||||
|
// workoutProvider.motivationBefore = 70;
|
||||||
|
// workoutProvider.motivationAfter = 80;
|
||||||
|
// workoutProvider.saveWorkout();
|
||||||
|
|
||||||
|
// // -> hier in datenbank nachschauen obs geklappt hat
|
||||||
|
// });
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,130 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:intl/date_symbol_data_local.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:smoke_cess_app/widgets/entry_detail_widget.dart';
|
||||||
|
import 'package:smoke_cess_app/widgets/history_list_widget.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
group('HistoryList', () {
|
||||||
|
initializeDateFormatting('de');
|
||||||
|
final List<String> history = ['1', '2', '3'];
|
||||||
|
dateSelector(String p0) => DateTime.now();
|
||||||
|
entryDataSelector(String p0) => p0;
|
||||||
|
|
||||||
|
testWidgets('should produce #(history.length) EntryDetail Widgets',
|
||||||
|
(widgetTester) async {
|
||||||
|
await widgetTester.pumpWidget(WrappedHistoryList(
|
||||||
|
history: history,
|
||||||
|
dateSelector: dateSelector,
|
||||||
|
entryDataSelector: entryDataSelector));
|
||||||
|
final widgetFinder = find.byType(EntryDetail);
|
||||||
|
final dateFinder =
|
||||||
|
find.text(DateFormat.MMMd('de').format(DateTime.now()));
|
||||||
|
//HistoryList uses Icons.circle as default if there is no IconData provided
|
||||||
|
final iconFinder = find.byIcon(Icons.circle);
|
||||||
|
expect(widgetFinder, findsNWidgets(history.length));
|
||||||
|
expect(dateFinder, findsNWidgets(history.length));
|
||||||
|
expect(iconFinder, findsNWidgets(history.length));
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets(
|
||||||
|
'should render correct icon if specified with icon selection function',
|
||||||
|
(widgetTester) async {
|
||||||
|
IconData iconDataSelector(String p0) => Icons.email;
|
||||||
|
|
||||||
|
await widgetTester.pumpWidget(WrappedHistoryList(
|
||||||
|
history: history,
|
||||||
|
dateSelector: dateSelector,
|
||||||
|
entryDataSelector: entryDataSelector,
|
||||||
|
iconDataSelector: iconDataSelector,
|
||||||
|
));
|
||||||
|
final circleIconFinder = find.byIcon(Icons.circle);
|
||||||
|
final correctIconFinder = find.byIcon(Icons.email);
|
||||||
|
|
||||||
|
expect(circleIconFinder, findsNothing);
|
||||||
|
expect(correctIconFinder, findsNWidgets(history.length));
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('icon field should overwrite iconSelector',
|
||||||
|
(widgetTester) async {
|
||||||
|
const IconData icon = Icons.abc;
|
||||||
|
IconData iconDataSelector(String p0) => Icons.email;
|
||||||
|
await widgetTester.pumpWidget(WrappedHistoryList(
|
||||||
|
history: history,
|
||||||
|
dateSelector: dateSelector,
|
||||||
|
entryDataSelector: entryDataSelector,
|
||||||
|
iconDataSelector: iconDataSelector,
|
||||||
|
icon: Icons.abc,
|
||||||
|
));
|
||||||
|
final circleIconFinder = find.byIcon(Icons.circle);
|
||||||
|
final emailIconFinder = find.byIcon(Icons.email);
|
||||||
|
final correctIconFinder = find.byIcon(icon);
|
||||||
|
|
||||||
|
expect(circleIconFinder, findsNothing);
|
||||||
|
expect(emailIconFinder, findsNothing);
|
||||||
|
expect(correctIconFinder, findsNWidgets(history.length));
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets(
|
||||||
|
'EntryDetails should display ExpansionTiles if entryComment is given',
|
||||||
|
(widgetTester) async {
|
||||||
|
String entryCommentSelector(String p0) => "";
|
||||||
|
await widgetTester.pumpWidget(WrappedHistoryList(
|
||||||
|
history: history,
|
||||||
|
dateSelector: dateSelector,
|
||||||
|
entryDataSelector: entryDataSelector,
|
||||||
|
entryCommentSelector: entryCommentSelector,
|
||||||
|
));
|
||||||
|
final expansionTileFinder = find.byType(ExpansionTile);
|
||||||
|
expect(expansionTileFinder, findsNWidgets(history.length));
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets(
|
||||||
|
'EntryDetails should display ExpansionTiles if entryComment is not given',
|
||||||
|
(widgetTester) async {
|
||||||
|
String entryCommentSelector(String p0) => "";
|
||||||
|
await widgetTester.pumpWidget(WrappedHistoryList(
|
||||||
|
history: history,
|
||||||
|
dateSelector: dateSelector,
|
||||||
|
entryDataSelector: entryDataSelector,
|
||||||
|
entryCommentSelector: entryCommentSelector,
|
||||||
|
));
|
||||||
|
final listTileFinder = find.byType(ListTile);
|
||||||
|
expect(listTileFinder, findsNWidgets(history.length));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class WrappedHistoryList<T> extends StatelessWidget {
|
||||||
|
final List<T> history;
|
||||||
|
final DateTime Function(T) dateSelector;
|
||||||
|
final String Function(T) entryDataSelector;
|
||||||
|
final IconData Function(T)? iconDataSelector;
|
||||||
|
final String Function(T)? entryCommentSelector;
|
||||||
|
final IconData? icon;
|
||||||
|
const WrappedHistoryList(
|
||||||
|
{super.key,
|
||||||
|
required this.history,
|
||||||
|
required this.dateSelector,
|
||||||
|
required this.entryDataSelector,
|
||||||
|
this.iconDataSelector,
|
||||||
|
this.icon,
|
||||||
|
this.entryCommentSelector});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return MaterialApp(
|
||||||
|
home: Scaffold(
|
||||||
|
body: Column(children: [
|
||||||
|
HistoryList<T>(
|
||||||
|
history: history,
|
||||||
|
dateSelector: dateSelector,
|
||||||
|
entryDataSelector: entryDataSelector,
|
||||||
|
icon: icon,
|
||||||
|
iconDataSelector: iconDataSelector,
|
||||||
|
entryCommentSelector: entryCommentSelector,
|
||||||
|
)
|
||||||
|
])));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue