Merge branch 'testing_branch' into 'main'
Testing branch See merge request Crondung/hsma_cpd!37main
commit
748c1cc585
|
@ -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
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
library app.globals;
|
||||
|
||||
import 'package:smoke_cess_app/mock/db_mock.dart';
|
||||
import 'package:smoke_cess_app/services/database_service.dart';
|
||||
|
||||
DatabaseService databaseService = DatabaseMock();
|
||||
// DatabaseService databaseService = DatabaseService.instance;
|
||||
DatabaseService databaseService = DatabaseService.instance;
|
||||
|
||||
// set this to read settings from local json file instead of scanning a qr code
|
||||
bool useLocalConfig = true;
|
||||
|
|
|
@ -22,7 +22,9 @@ class InputProvider extends ChangeNotifier {
|
|||
TextEditingController get textController => _textController;
|
||||
|
||||
set sliderValue(double newValue) {
|
||||
_sliderValue = newValue;
|
||||
if (_sliderValue > 0 && _sliderValue < 100) {
|
||||
_sliderValue = newValue;
|
||||
}
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ class SettingsProvider extends ChangeNotifier {
|
|||
initSettings();
|
||||
}
|
||||
|
||||
void initSettings() async {
|
||||
Future<void> initSettings() async {
|
||||
_settings = await loadSettings();
|
||||
_initialized = _settings != null ? true : false;
|
||||
notifyListeners();
|
||||
|
|
|
@ -31,7 +31,7 @@ class TasksProvider extends ChangeNotifier {
|
|||
notifyListeners();
|
||||
}
|
||||
|
||||
void initHistories() async {
|
||||
Future<void> initHistories() async {
|
||||
moodHistory = await globals.databaseService.getMoodRecords();
|
||||
sleepHistory = await globals.databaseService.getSleepRecords();
|
||||
workoutHistory = await globals.databaseService.getWorkoutRecords();
|
||||
|
|
|
@ -100,25 +100,25 @@ class WorkoutProvider extends ChangeNotifier {
|
|||
Map<WorkoutPhases, Map<String, dynamic>> _workoutPhaseSettings = {
|
||||
WorkoutPhases.warmUp: {
|
||||
'title': 'Warm Up',
|
||||
'duration': const Duration(seconds: 5),
|
||||
'duration': const Duration(minutes: 5),
|
||||
'source': AssetSource('warmUp.mp3'),
|
||||
'color': Colors.green
|
||||
},
|
||||
WorkoutPhases.highIntensity: {
|
||||
'title': 'High Intensity',
|
||||
'duration': const Duration(seconds: 4),
|
||||
'duration': const Duration(minutes: 4),
|
||||
'source': AssetSource('workout.mp3'),
|
||||
'color': Colors.red
|
||||
},
|
||||
WorkoutPhases.lowIntensity: {
|
||||
'title': 'Low Intensity',
|
||||
'duration': const Duration(seconds: 3),
|
||||
'duration': const Duration(minutes: 3),
|
||||
'source': AssetSource('workout.mp3'),
|
||||
'color': Colors.orange
|
||||
},
|
||||
WorkoutPhases.coolDown: {
|
||||
'title': 'Cool Down',
|
||||
'duration': const Duration(seconds: 5),
|
||||
'duration': const Duration(minutes: 5),
|
||||
'source': AssetSource('cool_down.mp3'),
|
||||
'color': Colors.blue
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ import 'package:timezone/timezone.dart';
|
|||
|
||||
import 'pages_service.dart';
|
||||
|
||||
const int trainingTime = 40;
|
||||
const int trainingTime = 6 * 7;
|
||||
|
||||
const weekDays = {
|
||||
"Montag": 1,
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
String formatTime(int seconds) {
|
||||
if (seconds < 0) {
|
||||
return '00:00';
|
||||
}
|
||||
Duration duration = Duration(seconds: seconds);
|
||||
String formattedTime = '';
|
||||
String twoDigits(int n) => n.toString().padLeft(2, "0");
|
||||
|
|
|
@ -13,8 +13,8 @@ class MoodForm extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var inputModel = context.watch<InputProvider>();
|
||||
var tasksModel = context.watch<TasksProvider>();
|
||||
InputProvider inputModel = context.watch<InputProvider>();
|
||||
TasksProvider tasksModel = context.watch<TasksProvider>();
|
||||
return ListView(
|
||||
padding: const EdgeInsets.fromLTRB(10, 10, 10, 10),
|
||||
children: [
|
||||
|
|
|
@ -27,7 +27,7 @@ class SleepView extends StatelessWidget {
|
|||
history: tasksModel.sleepHistory,
|
||||
dateSelector: (Sleep sleep) => sleep.date,
|
||||
entryDataSelector: (Sleep sleep) =>
|
||||
'${sleep.sleepDuration.hour}:${sleep.sleepDuration.minute}',
|
||||
'${sleep.sleepDuration.hour}:${sleep.sleepDuration.minute.toString().padLeft(2, "0")}',
|
||||
entryCommentSelector: (Sleep sleep) => 'Kommentar: ${sleep.comment}',
|
||||
icon: Icons.bedtime_outlined,
|
||||
)
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:smoke_cess_app/providers/input_provider.dart';
|
||||
import 'package:smoke_cess_app/providers/page_provider.dart';
|
||||
import 'package:smoke_cess_app/providers/tasks_provider.dart';
|
||||
import 'package:smoke_cess_app/widgets/view_form/mood_form.dart';
|
||||
import 'package:smoke_cess_app/globals.dart' as globals;
|
||||
import '../mock/db_mock.dart';
|
||||
|
||||
void main() {
|
||||
globals.databaseService = DatabaseMock();
|
||||
testWidgets('Mood Form saves correctly', (WidgetTester tester) async {
|
||||
const String testText = 'Its a test';
|
||||
// Create an instance of the Providers and add it to the widget tree
|
||||
final inputProvider = InputProvider();
|
||||
final tasksProvider = TasksProvider(null);
|
||||
final pageProvider = PageProvider();
|
||||
await tester.pumpWidget(
|
||||
MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider.value(value: inputProvider),
|
||||
ChangeNotifierProvider.value(value: tasksProvider),
|
||||
ChangeNotifierProvider.value(value: pageProvider),
|
||||
],
|
||||
child: const MaterialApp(
|
||||
home: Scaffold(
|
||||
body: MoodForm(),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.enterText(find.byType(TextField), testText);
|
||||
await tester.tap(find.byType(ElevatedButton));
|
||||
await tester.pump();
|
||||
final result = await globals.databaseService.getMoodRecords();
|
||||
expect(result.last.comment, testText);
|
||||
expect(result.last.moodValue, 50);
|
||||
});
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:intl/date_symbol_data_local.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:smoke_cess_app/models/mood.dart';
|
||||
import 'package:smoke_cess_app/providers/settings_provider.dart';
|
||||
import 'package:smoke_cess_app/providers/tasks_provider.dart';
|
||||
import 'package:smoke_cess_app/globals.dart' as globals;
|
||||
import 'package:smoke_cess_app/widgets/view_form/mood_view.dart';
|
||||
import '../mock/db_mock.dart';
|
||||
import '../mock/settings_mock.dart';
|
||||
|
||||
void main() {
|
||||
globals.databaseService = DatabaseMock();
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
SharedPreferences.setMockInitialValues(mockSettings);
|
||||
initializeDateFormatting('de');
|
||||
testWidgets('Mood View displays correctly', (WidgetTester tester) async {
|
||||
const String testText = 'Its a test';
|
||||
const int testValue = 30;
|
||||
// Create an instance of the Providers and add it to the widget tree
|
||||
final tasksProvider = TasksProvider(null);
|
||||
final settingsProvider = SettingsProvider();
|
||||
|
||||
await tester.pumpWidget(
|
||||
MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider.value(value: tasksProvider),
|
||||
ChangeNotifierProvider.value(value: settingsProvider),
|
||||
],
|
||||
child: const MaterialApp(
|
||||
home: Scaffold(
|
||||
body: MoodView(),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
await settingsProvider.initSettings();
|
||||
await globals.databaseService
|
||||
.addMood(Mood(testValue, testText, DateTime.now()));
|
||||
await tasksProvider.initHistories();
|
||||
await tester.pump();
|
||||
expect(find.text('Stimmung: $testValue'), findsOneWidget);
|
||||
await tester.tap(find.byIcon(Icons.expand_more));
|
||||
await tester.pump();
|
||||
expect(find.text('Kommentar: $testText'), findsOneWidget);
|
||||
});
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:smoke_cess_app/providers/input_provider.dart';
|
||||
import 'package:smoke_cess_app/providers/page_provider.dart';
|
||||
import 'package:smoke_cess_app/providers/settings_provider.dart';
|
||||
import 'package:smoke_cess_app/providers/tasks_provider.dart';
|
||||
import 'package:smoke_cess_app/globals.dart' as globals;
|
||||
import 'package:smoke_cess_app/widgets/drop_down.dart';
|
||||
import 'package:smoke_cess_app/widgets/view_form/relapse_form.dart';
|
||||
import '../mock/db_mock.dart';
|
||||
import '../mock/settings_mock.dart';
|
||||
|
||||
void main() {
|
||||
globals.databaseService = DatabaseMock();
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
SharedPreferences.setMockInitialValues(mockSettings);
|
||||
testWidgets('Relapse Form saves correctly', (WidgetTester tester) async {
|
||||
const String testText = 'Its a test';
|
||||
// Create an instance of the Providers and add it to the widget tree
|
||||
final inputProvider = InputProvider();
|
||||
final tasksProvider = TasksProvider(null);
|
||||
final pageProvider = PageProvider();
|
||||
final settingsProvider = SettingsProvider();
|
||||
await tester.pumpWidget(
|
||||
MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider.value(value: inputProvider),
|
||||
ChangeNotifierProvider.value(value: tasksProvider),
|
||||
ChangeNotifierProvider.value(value: pageProvider),
|
||||
ChangeNotifierProvider.value(value: settingsProvider),
|
||||
],
|
||||
child: const MaterialApp(
|
||||
home: Scaffold(
|
||||
body: RelapseForm(),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await settingsProvider.initSettings();
|
||||
|
||||
await tester.enterText(find.byType(TextField), testText);
|
||||
await tester.tap(find.byType(DropDown));
|
||||
await tester.pump();
|
||||
await tester
|
||||
.tap(find.text(settingsProvider.settings!.relapseCategories![1]).last);
|
||||
await tester.pump();
|
||||
await tester.tap(find.byType(ElevatedButton).last);
|
||||
await tester.pump();
|
||||
final result = await globals.databaseService.getRelapseRecords();
|
||||
expect(result.last.comment, testText);
|
||||
expect(
|
||||
result.last.category, settingsProvider.settings!.relapseCategories![1]);
|
||||
});
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:intl/date_symbol_data_local.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:smoke_cess_app/models/relapse.dart';
|
||||
import 'package:smoke_cess_app/providers/settings_provider.dart';
|
||||
import 'package:smoke_cess_app/providers/tasks_provider.dart';
|
||||
import 'package:smoke_cess_app/globals.dart' as globals;
|
||||
import 'package:smoke_cess_app/widgets/view_form/relapse_view.dart';
|
||||
import '../mock/db_mock.dart';
|
||||
import '../mock/settings_mock.dart';
|
||||
|
||||
void main() {
|
||||
globals.databaseService = DatabaseMock();
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
SharedPreferences.setMockInitialValues(mockSettings);
|
||||
initializeDateFormatting('de');
|
||||
testWidgets('Relapse View displays correctly', (WidgetTester tester) async {
|
||||
const String testText = 'Its a test';
|
||||
// Create an instance of the Providers and add it to the widget tree
|
||||
final tasksProvider = TasksProvider(null);
|
||||
final settingsProvider = SettingsProvider();
|
||||
|
||||
await tester.pumpWidget(
|
||||
MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider.value(value: tasksProvider),
|
||||
ChangeNotifierProvider.value(value: settingsProvider),
|
||||
],
|
||||
child: const MaterialApp(
|
||||
home: Scaffold(
|
||||
body: RelapseView(),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
await settingsProvider.initSettings();
|
||||
await globals.databaseService.addRelapse(Relapse(
|
||||
settingsProvider.settings!.relapseCategories![0],
|
||||
testText,
|
||||
DateTime.now(),
|
||||
));
|
||||
await tasksProvider.initHistories();
|
||||
await tester.pump();
|
||||
expect(find.text(settingsProvider.settings!.relapseCategories![0]),
|
||||
findsOneWidget);
|
||||
await tester.tap(find.byIcon(Icons.expand_more));
|
||||
await tester.pump();
|
||||
expect(find.text('Kommentar: $testText'), findsOneWidget);
|
||||
});
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:smoke_cess_app/providers/input_provider.dart';
|
||||
import 'package:smoke_cess_app/providers/page_provider.dart';
|
||||
import 'package:smoke_cess_app/providers/tasks_provider.dart';
|
||||
import 'package:smoke_cess_app/globals.dart' as globals;
|
||||
import 'package:smoke_cess_app/widgets/view_form/sleep_form.dart';
|
||||
import '../mock/db_mock.dart';
|
||||
|
||||
void main() {
|
||||
globals.databaseService = DatabaseMock();
|
||||
testWidgets('Sleep Form saves correctly', (WidgetTester tester) async {
|
||||
const String testText = 'Its a test';
|
||||
// Create an instance of the Providers and add it to the widget tree
|
||||
final inputProvider = InputProvider();
|
||||
final tasksProvider = TasksProvider(null);
|
||||
final pageProvider = PageProvider();
|
||||
await tester.pumpWidget(
|
||||
MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider.value(value: inputProvider),
|
||||
ChangeNotifierProvider.value(value: tasksProvider),
|
||||
ChangeNotifierProvider.value(value: pageProvider),
|
||||
],
|
||||
child: const MaterialApp(
|
||||
home: Scaffold(
|
||||
body: SleepForm(),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.enterText(find.byType(TextField), testText);
|
||||
await tester.tap(find.byType(ElevatedButton).last);
|
||||
await tester.pump();
|
||||
final result = await globals.databaseService.getSleepRecords();
|
||||
expect(result.last.comment, testText);
|
||||
expect(result.last.sleepQualitiyValue, 50);
|
||||
expect(result.last.sleepDuration, const TimeOfDay(hour: 10, minute: 0));
|
||||
});
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:intl/date_symbol_data_local.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:smoke_cess_app/models/sleep.dart';
|
||||
import 'package:smoke_cess_app/providers/settings_provider.dart';
|
||||
import 'package:smoke_cess_app/providers/tasks_provider.dart';
|
||||
import 'package:smoke_cess_app/globals.dart' as globals;
|
||||
import 'package:smoke_cess_app/widgets/view_form/sleep_view.dart';
|
||||
import '../mock/db_mock.dart';
|
||||
import '../mock/settings_mock.dart';
|
||||
|
||||
void main() {
|
||||
globals.databaseService = DatabaseMock();
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
SharedPreferences.setMockInitialValues(mockSettings);
|
||||
initializeDateFormatting('de');
|
||||
testWidgets('Sleep View displays correctly', (WidgetTester tester) async {
|
||||
const String testText = 'Its a test';
|
||||
const int testValue = 30;
|
||||
// Create an instance of the Providers and add it to the widget tree
|
||||
final tasksProvider = TasksProvider(null);
|
||||
final settingsProvider = SettingsProvider();
|
||||
|
||||
await tester.pumpWidget(
|
||||
MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider.value(value: tasksProvider),
|
||||
ChangeNotifierProvider.value(value: settingsProvider),
|
||||
],
|
||||
child: const MaterialApp(
|
||||
home: Scaffold(
|
||||
body: SleepView(),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
await settingsProvider.initSettings();
|
||||
await globals.databaseService.addSleep(Sleep(
|
||||
testValue,
|
||||
testText,
|
||||
DateTime.now(),
|
||||
const TimeOfDay(hour: 22, minute: 0),
|
||||
const TimeOfDay(hour: 8, minute: 0)));
|
||||
await tasksProvider.initHistories();
|
||||
await tester.pump();
|
||||
expect(find.text('10:00'), findsOneWidget);
|
||||
await tester.tap(find.byIcon(Icons.expand_more));
|
||||
await tester.pump();
|
||||
expect(find.text('Kommentar: $testText'), findsOneWidget);
|
||||
});
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
import 'package:audioplayers/audioplayers.dart';
|
||||
import 'package:smoke_cess_app/providers/audio_provider.dart';
|
||||
|
||||
class AudioProviderMock extends AudioProvider {
|
||||
@override
|
||||
bool get isMuted => true;
|
||||
|
||||
@override
|
||||
void stop() {}
|
||||
|
||||
@override
|
||||
void playFinishSound() {}
|
||||
|
||||
@override
|
||||
void mutePlayer() {}
|
||||
|
||||
@override
|
||||
void unMutePlayer() {}
|
||||
|
||||
@override
|
||||
void playSourceAfterBeep(AssetSource source) {}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
Map<String, Object> mockSettings = {
|
||||
"group": 3,
|
||||
"HITT_time": 35,
|
||||
"chess_time": {"hours": 8, "minutes": 30},
|
||||
"relapse_categories": ["App stresst mich", "langeweile", "lunge braucht es"],
|
||||
"mood_query": {
|
||||
"days": ["Montag", "Donnerstag"],
|
||||
"hours": 10,
|
||||
"minutes": 30
|
||||
},
|
||||
"sleep_query": {
|
||||
"days": ["Dienstag", "Samstag"],
|
||||
"hours": 15,
|
||||
"minutes": 42
|
||||
},
|
||||
"startedAt": DateTime.now().toIso8601String(),
|
||||
};
|
||||
|
||||
void mockSharedPreferences() =>
|
||||
SharedPreferences.setMockInitialValues(mockSettings);
|
|
@ -0,0 +1,124 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:shared_preferences/shared_preferences.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 '../mock/settings_mock.dart';
|
||||
|
||||
void main() async {
|
||||
tz.initializeTimeZones();
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
SharedPreferences.setMockInitialValues(mockSettings);
|
||||
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<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(['Mong'], 10, 0);
|
||||
expect(tzDateTimes, []);
|
||||
});
|
||||
|
||||
test('returns list of valid dates', () {
|
||||
List<TZDateTime> tzDateTimes = createTZDateTimes(['Montag'], 10, 0);
|
||||
expect(tzDateTimes.length, greaterThan(0));
|
||||
});
|
||||
|
||||
test('returns all the same days as today in next 6 weeks at 23:59', () {
|
||||
List<String> selectedDays = [
|
||||
weekDays.keys.elementAt(DateTime.now().weekday - 1)
|
||||
];
|
||||
List<TZDateTime> expected = [];
|
||||
DateTime now = DateTime.now();
|
||||
final Duration offset = now.timeZoneOffset;
|
||||
final DateTime date =
|
||||
DateTime(now.year, now.month, now.day, 23, 59, 0, 0, 0);
|
||||
for (int i = 0; i <= trainingTime; i = i + 7) {
|
||||
expected.add(
|
||||
TZDateTime.local(date.year, date.month, date.day, 23, 59, 0, 0, 0)
|
||||
.add(Duration(days: i))
|
||||
// subtract offset since TZDateTime uses the UTC Timezone
|
||||
.subtract(offset));
|
||||
}
|
||||
List<TZDateTime> result = createTZDateTimes(selectedDays, 23, 59);
|
||||
expect(result, expected);
|
||||
});
|
||||
});
|
||||
|
||||
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.timer);
|
||||
expect(duration, isNotNull);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
group('Helper functions', () {
|
||||
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'];
|
||||
const selectedHours = 12;
|
||||
const selectedMinutes = 30;
|
||||
final result =
|
||||
createTZDateTimes(selectedDays, selectedHours, selectedMinutes);
|
||||
expect(result, isA<List<TZDateTime>>());
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:smoke_cess_app/providers/input_provider.dart';
|
||||
import 'package:smoke_cess_app/globals.dart' as globals;
|
||||
|
||||
import '../mock/db_mock.dart';
|
||||
|
||||
void main() {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
globals.databaseService = DatabaseMock();
|
||||
group('InputProvider', () {
|
||||
test('Initial values are correct', () {
|
||||
late final inputProvider = InputProvider();
|
||||
|
||||
expect(inputProvider.sliderValue, equals(50));
|
||||
expect(inputProvider.textController.text, equals(''));
|
||||
expect(inputProvider.relapseCategory, equals(''));
|
||||
expect(inputProvider.getTimeEntry(SleepTimes.wokeUpAt),
|
||||
equals(const TimeOfDay(hour: 8, minute: 0)));
|
||||
expect(inputProvider.getTimeEntry(SleepTimes.sleptAt),
|
||||
equals(const TimeOfDay(hour: 22, minute: 0)));
|
||||
});
|
||||
|
||||
test('Setters work right way', () {
|
||||
late final inputProvider = InputProvider();
|
||||
|
||||
inputProvider.sliderValue = 75;
|
||||
expect(inputProvider.sliderValue, equals(75));
|
||||
|
||||
inputProvider.textController.text = 'Test';
|
||||
expect(inputProvider.textController.text, equals('Test'));
|
||||
|
||||
inputProvider.relapseCategory = 'Test';
|
||||
expect(inputProvider.relapseCategory, equals('Test'));
|
||||
|
||||
inputProvider.setTime(
|
||||
SleepTimes.wokeUpAt, const TimeOfDay(hour: 7, minute: 0));
|
||||
expect(inputProvider.getTimeEntry(SleepTimes.wokeUpAt),
|
||||
equals(const TimeOfDay(hour: 7, minute: 0)));
|
||||
|
||||
inputProvider.setTime(
|
||||
SleepTimes.sleptAt, const TimeOfDay(hour: 23, minute: 0));
|
||||
expect(inputProvider.getTimeEntry(SleepTimes.sleptAt),
|
||||
equals(const TimeOfDay(hour: 23, minute: 0)));
|
||||
});
|
||||
test('Reset Fields should reset all fields correctly', () async {
|
||||
final inputProvider = InputProvider();
|
||||
|
||||
inputProvider.sliderValue = 44;
|
||||
inputProvider.textController.text = 'Test';
|
||||
inputProvider.setTime(
|
||||
SleepTimes.wokeUpAt, const TimeOfDay(hour: 7, minute: 0));
|
||||
inputProvider.setTime(
|
||||
SleepTimes.sleptAt, const TimeOfDay(hour: 23, minute: 0));
|
||||
|
||||
final result =
|
||||
await inputProvider.saveMood(); // calls private function ResetFields
|
||||
|
||||
expect(result, equals(1));
|
||||
expect(inputProvider.sliderValue, equals(50));
|
||||
expect(inputProvider.textController.text, equals(''));
|
||||
expect(inputProvider.getTimeEntry(SleepTimes.wokeUpAt),
|
||||
equals(const TimeOfDay(hour: 8, minute: 0)));
|
||||
expect(inputProvider.getTimeEntry(SleepTimes.sleptAt),
|
||||
equals(const TimeOfDay(hour: 22, minute: 0)));
|
||||
});
|
||||
test('Save Mood ', () async {
|
||||
late final inputProvider = InputProvider();
|
||||
|
||||
final result = await inputProvider.saveMood();
|
||||
|
||||
expect(result, equals(1));
|
||||
expect(inputProvider.sliderValue, equals(50));
|
||||
expect(inputProvider.textController.text, equals(''));
|
||||
});
|
||||
|
||||
test('Save Relapse', () async {
|
||||
late final inputProvider = InputProvider();
|
||||
|
||||
final result = await inputProvider.saveRelapse();
|
||||
|
||||
expect(result, equals(1));
|
||||
expect(inputProvider.relapseCategory, equals(''));
|
||||
expect(inputProvider.textController.text, equals(''));
|
||||
});
|
||||
|
||||
test('Save Sleep', () async {
|
||||
late final inputProvider = InputProvider();
|
||||
|
||||
final result = await inputProvider.saveSleep(
|
||||
SleepTimes.wokeUpAt, SleepTimes.sleptAt);
|
||||
|
||||
expect(result, equals(1));
|
||||
expect(inputProvider.sliderValue, equals(50));
|
||||
expect(inputProvider.textController.text, equals(''));
|
||||
expect(inputProvider.getTimeEntry(SleepTimes.wokeUpAt),
|
||||
equals(const TimeOfDay(hour: 8, minute: 0)));
|
||||
expect(inputProvider.getTimeEntry(SleepTimes.sleptAt),
|
||||
equals(const TimeOfDay(hour: 22, minute: 0)));
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:smoke_cess_app/providers/settings_provider.dart';
|
||||
import '../mock/settings_mock.dart';
|
||||
|
||||
void main() {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
SharedPreferences.setMockInitialValues(mockSettings);
|
||||
group('SettingsProvider', () {
|
||||
test('initial state', () {
|
||||
final provider = SettingsProvider();
|
||||
expect(provider.settings, isNull);
|
||||
expect(provider.initialized, isFalse);
|
||||
expect(provider.scanning, isFalse);
|
||||
});
|
||||
|
||||
test('initialize mocksettings', () async {
|
||||
final provider = SettingsProvider();
|
||||
await provider.initSettings();
|
||||
expect(provider.settings, isNotNull);
|
||||
expect(provider.initialized, isTrue);
|
||||
expect(provider.settings?.group, 3);
|
||||
});
|
||||
|
||||
test('set scanning', () {
|
||||
final provider = SettingsProvider();
|
||||
provider.scanning = true;
|
||||
expect(provider.scanning, isTrue);
|
||||
provider.scanning = false;
|
||||
expect(provider.scanning, isFalse);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:smoke_cess_app/providers/timer_provider.dart';
|
||||
|
||||
void main() {
|
||||
test('Timer should start and set started to true', () {
|
||||
final timerProvider = TimerProvider();
|
||||
timerProvider.startTimer(const Duration(seconds: 10));
|
||||
expect(timerProvider.started, true);
|
||||
});
|
||||
|
||||
test('Elapsed time should increase and be less than or equal to the duration',
|
||||
() {
|
||||
final timerProvider = TimerProvider();
|
||||
timerProvider.startTimer(const Duration(seconds: 10));
|
||||
final initialElapsedSeconds = timerProvider.elapsedSeconds;
|
||||
// Wait for the timer to tick at least once.
|
||||
Future.delayed(const Duration(seconds: 2), () {
|
||||
expect(timerProvider.elapsedSeconds, greaterThan(initialElapsedSeconds));
|
||||
expect(timerProvider.elapsedSeconds, lessThanOrEqualTo(10));
|
||||
});
|
||||
});
|
||||
|
||||
test('Timer should stop and set started to false', () {
|
||||
final timerProvider = TimerProvider();
|
||||
timerProvider.startTimer(const Duration(seconds: 10));
|
||||
timerProvider.stopTimer();
|
||||
expect(timerProvider.started, false);
|
||||
});
|
||||
|
||||
test('Elapsed seconds should be 0 when timer is not running', () {
|
||||
final timerProvider = TimerProvider();
|
||||
expect(timerProvider.elapsedSeconds, 0);
|
||||
});
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:smoke_cess_app/utils/timer_util.dart';
|
||||
|
||||
void main() {
|
||||
test('FormatTime: Seconds', () {
|
||||
String result = formatTime(1);
|
||||
expect(result, '00:01');
|
||||
});
|
||||
test('FormatTime: Minutes', () {
|
||||
String result = formatTime(61);
|
||||
expect(result, '01:01');
|
||||
});
|
||||
test('FormatTime: Hours', () {
|
||||
String result = formatTime(3661);
|
||||
expect(result, '01:01:01');
|
||||
});
|
||||
test('FormatTime: Day', () {
|
||||
String result = formatTime(90061);
|
||||
expect(result, '1 Tag, 01:01:01');
|
||||
});
|
||||
test('FormatTime: Days', () {
|
||||
String result = formatTime(176461);
|
||||
expect(result, '2 Tage, 01:01:01');
|
||||
});
|
||||
test('FormatTime: Negativ Value', () {
|
||||
String result = formatTime(-1);
|
||||
expect(result, '00:00');
|
||||
});
|
||||
|
||||
test('DurationBetween: 0', () {
|
||||
TimeOfDay start = const TimeOfDay(hour: 12, minute: 0);
|
||||
TimeOfDay end = const TimeOfDay(hour: 12, minute: 0);
|
||||
TimeOfDay result = start.durationBetween(end);
|
||||
expect(result, const TimeOfDay(hour: 0, minute: 0));
|
||||
});
|
||||
test('DurationBetween: 23h 59min', () {
|
||||
TimeOfDay start = const TimeOfDay(hour: 0, minute: 0);
|
||||
TimeOfDay end = const TimeOfDay(hour: 23, minute: 59);
|
||||
TimeOfDay result = start.durationBetween(end);
|
||||
expect(result, const TimeOfDay(hour: 23, minute: 59));
|
||||
});
|
||||
test('DurationBetween: 12h 34min', () {
|
||||
TimeOfDay start = const TimeOfDay(hour: 2, minute: 12);
|
||||
TimeOfDay end = const TimeOfDay(hour: 14, minute: 46);
|
||||
TimeOfDay result = start.durationBetween(end);
|
||||
expect(result, const TimeOfDay(hour: 12, minute: 34));
|
||||
});
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
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';
|
||||
import 'package:smoke_cess_app/globals.dart' as globals;
|
||||
import '../mock/audio_provider_mock.dart';
|
||||
import '../mock/db_mock.dart';
|
||||
|
||||
void main() {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
globals.databaseService = DatabaseMock();
|
||||
group('WorkoutProvider', () {
|
||||
late WorkoutProvider workoutProvider;
|
||||
late TimerProvider timerProvider;
|
||||
late AudioProvider audioProvider;
|
||||
|
||||
setUp(() {
|
||||
timerProvider = TimerProvider();
|
||||
audioProvider = AudioProviderMock();
|
||||
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(minutes: 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(minutes: 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(minutes: 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', () async {
|
||||
workoutProvider.motivationBefore = 70;
|
||||
workoutProvider.motivationAfter = 80;
|
||||
workoutProvider.saveWorkout();
|
||||
|
||||
final result = await globals.databaseService.getWorkoutRecords();
|
||||
|
||||
expect(result.length, 1);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
// This is a basic Flutter widget test.
|
||||
//
|
||||
// To perform an interaction with a widget in your test, use the WidgetTester
|
||||
// utility in the flutter_test package. For example, you can send tap and scroll
|
||||
// gestures. You can also use WidgetTester to find child widgets in the widget
|
||||
// tree, read text, and verify that the values of widget properties are correct.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'package:smoke_cess_app/main.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
|
||||
// Build our app and trigger a frame.
|
||||
await tester.pumpWidget(const MyApp());
|
||||
|
||||
// Verify that our counter starts at 0.
|
||||
expect(find.text('0'), findsOneWidget);
|
||||
expect(find.text('1'), findsNothing);
|
||||
|
||||
// Tap the '+' icon and trigger a frame.
|
||||
await tester.tap(find.byIcon(Icons.add));
|
||||
await tester.pump();
|
||||
|
||||
// Verify that our counter has incremented.
|
||||
expect(find.text('0'), findsNothing);
|
||||
expect(find.text('1'), findsOneWidget);
|
||||
});
|
||||
}
|
|
@ -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,
|
||||
)
|
||||
])));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:smoke_cess_app/providers/audio_provider.dart';
|
||||
import 'package:smoke_cess_app/widgets/buttons/mute_button.dart';
|
||||
|
||||
void main() {
|
||||
group('MuteButton', () {
|
||||
testWidgets('should handle mute logic', (WidgetTester tester) async {
|
||||
AudioProvider audioProvider = AudioProvider();
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Scaffold(
|
||||
body: ChangeNotifierProvider(
|
||||
create: (context) => audioProvider,
|
||||
child: const MuteButton()))),
|
||||
);
|
||||
final button = find.byType(IconButton);
|
||||
final mutedIcon = find.byIcon(Icons.volume_off_outlined);
|
||||
final unMutedIcon = find.byIcon(Icons.volume_up_outlined);
|
||||
expect(audioProvider.isMuted, false);
|
||||
expect(button, findsOneWidget);
|
||||
expect(mutedIcon, findsNothing);
|
||||
expect(unMutedIcon, findsOneWidget);
|
||||
|
||||
await tester.tap(unMutedIcon);
|
||||
await tester.pump();
|
||||
|
||||
expect(audioProvider.isMuted, true);
|
||||
expect(mutedIcon, findsOneWidget);
|
||||
expect(unMutedIcon, findsNothing);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mobile_scanner/mobile_scanner.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:smoke_cess_app/providers/settings_provider.dart';
|
||||
import 'package:smoke_cess_app/widgets/buttons/text_icon_button.dart';
|
||||
import 'package:smoke_cess_app/widgets/scanner.dart';
|
||||
|
||||
import '../mock/settings_mock.dart';
|
||||
|
||||
void main() {
|
||||
mockSharedPreferences();
|
||||
|
||||
group('MyScanner', () {
|
||||
testWidgets('Scanner should start after Button is pressed',
|
||||
(widgetTester) async {
|
||||
SettingsProvider settingsProvider = SettingsProvider();
|
||||
expect(settingsProvider.scanning, false);
|
||||
|
||||
await widgetTester.pumpWidget(MaterialApp(
|
||||
home: Column(
|
||||
children: [
|
||||
ChangeNotifierProvider(
|
||||
create: (context) => settingsProvider, child: const MyScanner())
|
||||
],
|
||||
),
|
||||
));
|
||||
|
||||
final startScannerButton = find.byType(TextIconButton);
|
||||
final scanner = find.byType(MobileScanner);
|
||||
expect(startScannerButton, findsOneWidget);
|
||||
expect(scanner, findsNothing);
|
||||
|
||||
await widgetTester.tap(startScannerButton);
|
||||
await widgetTester.pump();
|
||||
expect(startScannerButton, findsNothing);
|
||||
expect(scanner, findsOneWidget);
|
||||
expect(settingsProvider.scanning, true);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:smoke_cess_app/providers/timer_provider.dart';
|
||||
import 'package:smoke_cess_app/utils/timer_util.dart';
|
||||
import 'package:smoke_cess_app/widgets/timer_widget.dart';
|
||||
|
||||
void main() {
|
||||
group('TimerWidget', () {
|
||||
testWidgets('should display duration', (WidgetTester tester) async {
|
||||
TimerProvider timerProvider = TimerProvider();
|
||||
Duration duration = const Duration(minutes: 1);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Scaffold(
|
||||
body: ChangeNotifierProvider(
|
||||
create: (context) => timerProvider,
|
||||
child: TimerWidget(duration: duration)))),
|
||||
);
|
||||
|
||||
final durationTextFinder = find.text(formatTime(duration.inSeconds));
|
||||
expect(durationTextFinder, findsOneWidget);
|
||||
|
||||
timerProvider.startTimer(duration);
|
||||
await tester.pump(const Duration(seconds: 1));
|
||||
expect(durationTextFinder, findsNothing);
|
||||
expect(find.text(formatTime(duration.inSeconds - 1)), findsOneWidget);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:smoke_cess_app/providers/input_provider.dart';
|
||||
import 'package:smoke_cess_app/widgets/drop_down.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('DropDown should display items and update input model',
|
||||
(WidgetTester tester) async {
|
||||
// Define the list of items
|
||||
final items = ['Item 1', 'Item 2', 'Item 3'];
|
||||
|
||||
// Create an instance of the InputProvider and add it to the widget tree
|
||||
final inputProvider = InputProvider();
|
||||
await tester.pumpWidget(
|
||||
MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider.value(value: inputProvider),
|
||||
],
|
||||
child: MaterialApp(
|
||||
home: Scaffold(
|
||||
body: DropDown(items),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Verify that the DropDown displays the first item
|
||||
expect(find.text(items[0]), findsOneWidget);
|
||||
|
||||
// Tap the DropDown to open the menu
|
||||
await tester.tap(find.byType(DropDown));
|
||||
await tester.pump();
|
||||
|
||||
// Verify that the menu displays the correct items
|
||||
for (final item in items) {
|
||||
expect(find.text(item).first, findsOneWidget);
|
||||
}
|
||||
|
||||
// Select the second item
|
||||
await tester.tap(find.text(items[1]).last);
|
||||
await tester.pump();
|
||||
|
||||
// Verify that the input model was updated with the selected item
|
||||
expect(inputProvider.relapseCategory, equals(items[1]));
|
||||
});
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:smoke_cess_app/widgets/elevated_card.dart';
|
||||
|
||||
void main() {
|
||||
group('ElevatedCard', () {
|
||||
testWidgets('Renders the title and child', (WidgetTester tester) async {
|
||||
// Arrange
|
||||
const title = 'My Card Title';
|
||||
const childText = 'My Card Content';
|
||||
const child = Text(childText);
|
||||
const card = ElevatedCard(title: title, child: child);
|
||||
|
||||
// Act
|
||||
await tester.pumpWidget(const MaterialApp(home: Scaffold(body: card)));
|
||||
final titleFinder = find.text(title);
|
||||
final childFinder = find.text(childText);
|
||||
|
||||
// Assert
|
||||
expect(titleFinder, findsOneWidget);
|
||||
expect(childFinder, findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Uses default title style', (WidgetTester tester) async {
|
||||
// Arrange
|
||||
final card = ElevatedCard(title: 'My Title', child: Container());
|
||||
|
||||
// Act
|
||||
await tester.pumpWidget(MaterialApp(home: Scaffold(body: card)));
|
||||
final titleFinder = find.text('My Title');
|
||||
final titleWidget = tester.widget<Text>(titleFinder);
|
||||
|
||||
// Assert
|
||||
expect(titleWidget.style?.fontSize, equals(16.0));
|
||||
expect(titleWidget.style?.fontWeight, equals(FontWeight.bold));
|
||||
});
|
||||
|
||||
testWidgets('Uses custom title style', (WidgetTester tester) async {
|
||||
// Arrange
|
||||
final card = ElevatedCard(
|
||||
title: 'My Title',
|
||||
child: Container(),
|
||||
);
|
||||
|
||||
// Act
|
||||
await tester.pumpWidget(MaterialApp(home: Scaffold(body: card)));
|
||||
final titleFinder = find.text('My Title');
|
||||
final titleWidget = tester.widget<Text>(titleFinder);
|
||||
|
||||
// Assert
|
||||
expect(titleWidget.style?.fontSize, equals(16.0));
|
||||
expect(titleWidget.style?.fontWeight, equals(FontWeight.bold));
|
||||
});
|
||||
|
||||
testWidgets('Has rounded corners', (WidgetTester tester) async {
|
||||
// Arrange
|
||||
final card = ElevatedCard(title: 'My Title', child: Container());
|
||||
|
||||
// Act
|
||||
await tester.pumpWidget(MaterialApp(home: Scaffold(body: card)));
|
||||
final cardFinder = find.byType(Card);
|
||||
final cardWidget = tester.widget<Card>(cardFinder);
|
||||
|
||||
// Assert
|
||||
expect(
|
||||
cardWidget.shape,
|
||||
const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(16.0))));
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:intl/date_symbol_data_local.dart';
|
||||
import 'package:smoke_cess_app/widgets/entry_detail_widget.dart';
|
||||
|
||||
void main() {
|
||||
initializeDateFormatting('de');
|
||||
group('EntryDetail', () {
|
||||
testWidgets('should use ExpansionTile if Comments is set',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Scaffold(
|
||||
body: EntryDetail(
|
||||
date: DateTime.now(),
|
||||
entryComment: 'A comment',
|
||||
entryData: 'Test',
|
||||
iconData: Icons.plus_one,
|
||||
),
|
||||
)),
|
||||
);
|
||||
|
||||
expect(find.byType(ExpansionTile), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('should use ListTile if Comments is null',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Scaffold(
|
||||
body: EntryDetail(
|
||||
date: DateTime.now(),
|
||||
entryComment: 'A comment',
|
||||
entryData: 'Test',
|
||||
iconData: Icons.plus_one,
|
||||
),
|
||||
)),
|
||||
);
|
||||
|
||||
expect(find.byType(ListTile), findsOneWidget);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:smoke_cess_app/providers/input_provider.dart';
|
||||
import 'package:smoke_cess_app/widgets/slider.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('Slider starts at 50', (WidgetTester tester) async {
|
||||
// Create an instance of the InputProvider and add it to the widget tree
|
||||
final inputProvider = InputProvider();
|
||||
await tester.pumpWidget(
|
||||
MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider.value(value: inputProvider),
|
||||
],
|
||||
child: const MaterialApp(
|
||||
home: Scaffold(
|
||||
body: MySlider(),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Verify that the Slider displays 50
|
||||
expect(find.text('50'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Slider puts 51 after Tap on plus in InputProvider',
|
||||
(WidgetTester tester) async {
|
||||
final inputProvider = InputProvider();
|
||||
await tester.pumpWidget(
|
||||
MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider.value(value: inputProvider),
|
||||
],
|
||||
child: const MaterialApp(
|
||||
home: Scaffold(
|
||||
body: MySlider(),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.byIcon(Icons.add_outlined));
|
||||
await tester.pump();
|
||||
|
||||
expect(inputProvider.sliderValue, equals(51));
|
||||
});
|
||||
|
||||
testWidgets('Slider puts 49 after Tap on subtract in InputProvider',
|
||||
(WidgetTester tester) async {
|
||||
final inputProvider = InputProvider();
|
||||
await tester.pumpWidget(
|
||||
MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider.value(value: inputProvider),
|
||||
],
|
||||
child: const MaterialApp(
|
||||
home: Scaffold(
|
||||
body: MySlider(),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.byIcon(Icons.remove_outlined));
|
||||
await tester.pump();
|
||||
|
||||
expect(inputProvider.sliderValue, equals(49));
|
||||
});
|
||||
|
||||
testWidgets('Slider doesnt go higher than 100', (WidgetTester tester) async {
|
||||
final inputProvider = InputProvider();
|
||||
await tester.pumpWidget(
|
||||
MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider.value(value: inputProvider),
|
||||
],
|
||||
child: const MaterialApp(
|
||||
home: Scaffold(
|
||||
body: MySlider(),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
await tester.tap(find.byIcon(Icons.add_outlined));
|
||||
await tester.pump();
|
||||
}
|
||||
|
||||
expect(inputProvider.sliderValue, equals(100));
|
||||
});
|
||||
|
||||
testWidgets('Slider doesnt go lower than 0', (WidgetTester tester) async {
|
||||
final inputProvider = InputProvider();
|
||||
await tester.pumpWidget(
|
||||
MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider.value(value: inputProvider),
|
||||
],
|
||||
child: const MaterialApp(
|
||||
home: Scaffold(
|
||||
body: MySlider(),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
await tester.tap(find.byIcon(Icons.remove_outlined));
|
||||
await tester.pump();
|
||||
}
|
||||
|
||||
expect(inputProvider.sliderValue, equals(0));
|
||||
});
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:smoke_cess_app/providers/input_provider.dart';
|
||||
import 'package:smoke_cess_app/widgets/text_formfield.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('TextFormField initial Value is correct',
|
||||
(WidgetTester tester) async {
|
||||
const String testText = 'Its a test';
|
||||
// Create an instance of the InputProvider and add it to the widget tree
|
||||
final inputProvider = InputProvider();
|
||||
await tester.pumpWidget(
|
||||
MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider.value(value: inputProvider),
|
||||
],
|
||||
child: const MaterialApp(
|
||||
home: Scaffold(
|
||||
body: MyTextFormField(testText),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Verify that the Slider displays 50
|
||||
expect(find.text(testText), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('TextFormField inputs correctly to Provider',
|
||||
(WidgetTester tester) async {
|
||||
const String testText = 'Its a test';
|
||||
// Create an instance of the InputProvider and add it to the widget tree
|
||||
final inputProvider = InputProvider();
|
||||
await tester.pumpWidget(
|
||||
MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider.value(value: inputProvider),
|
||||
],
|
||||
child: const MaterialApp(
|
||||
home: Scaffold(
|
||||
body: MyTextFormField(testText),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.enterText(find.byType(TextField), testText);
|
||||
expect(inputProvider.textController.text, testText);
|
||||
});
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:smoke_cess_app/widgets/todo_icon.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('MyToDoIcon has a red dot', (WidgetTester tester) async {
|
||||
// Build the widget tree
|
||||
await tester.pumpWidget(
|
||||
const MaterialApp(
|
||||
home: Scaffold(
|
||||
body: MyToDoIcon(
|
||||
Icon(Icons.check),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Verify that the red dot is present
|
||||
expect(find.byIcon(Icons.brightness_1), findsOneWidget);
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue