From bb833f4bfe8d38c2d0a88a4fea5494449667ae04 Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Mon, 6 Mar 2023 19:30:37 +0100 Subject: [PATCH 1/5] test EntryDetailTitle --- .../widget_entry_detail_test.dart | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 test/widget_tests/widget_entry_detail_test.dart diff --git a/test/widget_tests/widget_entry_detail_test.dart b/test/widget_tests/widget_entry_detail_test.dart new file mode 100644 index 0000000..a741ab5 --- /dev/null +++ b/test/widget_tests/widget_entry_detail_test.dart @@ -0,0 +1,24 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:intl/intl.dart'; +import 'package:intl/date_symbol_data_local.dart'; + +import 'package:smoke_cess_app/widgets/entry_detail_title.dart'; + +void main() { + group('EntryDetailTitle', () { + DateTime date = DateTime.now(); + String entryData = "TestEntryData"; + initializeDateFormatting('de'); + + testWidgets('EntryDetailTitle has formatted date and entrydata', + (widgetTester) async { + await widgetTester.pumpWidget(MaterialApp( + home: EntryDetailTitle(date: date, entryData: entryData))); + final formattedDateFinder = find.text(DateFormat.MMMd('de').format(date)); + final entryDataFinder = find.text(entryData); + expect(formattedDateFinder, findsOneWidget); + expect(entryDataFinder, findsOneWidget); + }); + }); +} From a9480cc5080279811c6dc0f5a4bd6f7f33506406 Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Mon, 6 Mar 2023 19:31:37 +0100 Subject: [PATCH 2/5] add tests to pipeline --- .gitlab-ci.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4bb6e7e..52497a7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,6 +2,7 @@ image: cirrusci/flutter:3.7.5 stages: - analyze + - test before_script: - flutter pub get @@ -13,3 +14,10 @@ analyze: - flutter analyze only: - merge_requests + +test: + stage: test + script: + - flutter test + only: + - merge_requests From d6a45e8974bd8d96d271850de6252ef204524272 Mon Sep 17 00:00:00 2001 From: "h.ehrenfried" <2012537@stud.hs-mannheim.de> Date: Mon, 6 Mar 2023 20:38:53 +0100 Subject: [PATCH 3/5] create workout & settings Provider and date service tests --- test/unit_tests/date_service_test.dart | 118 ++++++++++++++++++++ test/unit_tests/settings_provider_test.dart | 28 +++++ test/unit_tests/workout_provider_test.dart | 75 +++++++++++++ 3 files changed, 221 insertions(+) create mode 100644 test/unit_tests/date_service_test.dart create mode 100644 test/unit_tests/settings_provider_test.dart create mode 100644 test/unit_tests/workout_provider_test.dart diff --git a/test/unit_tests/date_service_test.dart b/test/unit_tests/date_service_test.dart new file mode 100644 index 0000000..13bf03b --- /dev/null +++ b/test/unit_tests/date_service_test.dart @@ -0,0 +1,118 @@ +import 'package:flutter_test/flutter_test.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'; + +void main() { + group('Helpers', () { + group('isSameDay', () { + test('returns true when dates are the same day', () { + DateTime dateA = DateTime.now(); + DateTime dateB = DateTime(dateA.year, dateA.month, dateA.day, 10, 0); + expect(isSameDay(dateA, dateB), true); + }); + + 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 tzDateTimes = + createTZDateTimes(null, 10, 0); + expect(tzDateTimes, []); + }); + + test('returns empty list when selectedHours is null', () { + List tzDateTimes = + createTZDateTimes(['Montag'], null, 0); + expect(tzDateTimes, []); + }); + + test('returns empty list when selectedMinutes is null', () { + List tzDateTimes = + createTZDateTimes(['Montag'], 10, null); + expect(tzDateTimes, []); + }); + + test('returns empty list when no valid dates are found', () { + List tzDateTimes = + createTZDateTimes(['Montag'], 10, 0); + expect(tzDateTimes, []); + }); + + test('returns list of valid dates', () { + List 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); + }); + + test('isSameDay returns false if two dates are not the same day', () { + final date1 = DateTime(2022, 3, 6); + final date2 = DateTime(2022, 3, 7); + final result = isSameDay(date1, date2); + expect(result, false); + }); + + test('createTZDateTimes returns a list of TZDateTime objects', () async { + final selectedDays = ['Montag', 'Dienstag']; + final selectedHours = 12; + final selectedMinutes = 30; + final result = await createTZDateTimes( + selectedDays, selectedHours, selectedMinutes); + expect(result, isA>()); + }); + }); + + +} diff --git a/test/unit_tests/settings_provider_test.dart b/test/unit_tests/settings_provider_test.dart new file mode 100644 index 0000000..4d43184 --- /dev/null +++ b/test/unit_tests/settings_provider_test.dart @@ -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); + }); + }); +} diff --git a/test/unit_tests/workout_provider_test.dart b/test/unit_tests/workout_provider_test.dart new file mode 100644 index 0000000..31d7784 --- /dev/null +++ b/test/unit_tests/workout_provider_test.dart @@ -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 + // }); + }); +} From 6c0708ca77eb96d735fbcc7f7f59454b32ec5c45 Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Mon, 6 Mar 2023 20:52:35 +0100 Subject: [PATCH 4/5] historylist test --- test/widget_tests/history_list_test.dart | 102 +++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 test/widget_tests/history_list_test.dart diff --git a/test/widget_tests/history_list_test.dart b/test/widget_tests/history_list_test.dart new file mode 100644 index 0000000..3ed6809 --- /dev/null +++ b/test/widget_tests/history_list_test.dart @@ -0,0 +1,102 @@ +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 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)); + }); + }); +} + +class WrappedHistoryList extends StatelessWidget { + final List 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( + history: history, + dateSelector: dateSelector, + entryDataSelector: entryDataSelector, + icon: icon, + iconDataSelector: iconDataSelector, + entryCommentSelector: entryCommentSelector, + ) + ]))); + } +} From 57d3b22c1be2275ac8bd697e129ae7befa8b528c Mon Sep 17 00:00:00 2001 From: Crondung <1922635@stud.hs-mannheim.de> Date: Mon, 6 Mar 2023 21:00:05 +0100 Subject: [PATCH 5/5] completed history list test --- test/widget_tests/history_list_test.dart | 28 ++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/test/widget_tests/history_list_test.dart b/test/widget_tests/history_list_test.dart index 3ed6809..7354473 100644 --- a/test/widget_tests/history_list_test.dart +++ b/test/widget_tests/history_list_test.dart @@ -65,6 +65,34 @@ void main() { 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)); + }); }); }