mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-07-04 14:23:16 +02:00
- C/lichess_random_engine, vocabulary_curve, misc/split, 1dvelocitysimulator, opening_learner: test suites added - CPP/miscelanious: tests added - TS/battery-status, champions_leauge_scores, two-inputs: tests added - python_pkg/fm24_searcher, wake_alarm: new packages added - Fix ruff/cppcheck/eslint/clang-format failures - Update .gitignore for C/C++ build artifacts
230 lines
6.1 KiB
Dart
230 lines
6.1 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:pomodoro_app/models/pomodoro_state.dart';
|
|
import 'package:pomodoro_app/screens/pomodoro_screen.dart';
|
|
import 'package:pomodoro_app/services/pomodoro_timer.dart';
|
|
|
|
/// Controllable fake timer for widget tests.
|
|
class FakeTimerController {
|
|
void Function(Timer)? _callback;
|
|
bool _isActive = true;
|
|
|
|
void tick() {
|
|
if (_isActive) {
|
|
_callback?.call(_FakeTimer(this));
|
|
}
|
|
}
|
|
|
|
void cancel() {
|
|
_isActive = false;
|
|
}
|
|
|
|
bool get isActive => _isActive;
|
|
}
|
|
|
|
class _FakeTimer implements Timer {
|
|
_FakeTimer(this._controller);
|
|
final FakeTimerController _controller;
|
|
|
|
@override
|
|
void cancel() => _controller.cancel();
|
|
|
|
@override
|
|
bool get isActive => _controller.isActive;
|
|
|
|
@override
|
|
int get tick => 0;
|
|
}
|
|
|
|
void main() {
|
|
late PomodoroTimer timer;
|
|
late FakeTimerController fakeController;
|
|
|
|
Timer fakeTimerFactory(Duration duration, void Function(Timer) callback) {
|
|
fakeController = FakeTimerController()
|
|
.._callback = callback;
|
|
return _FakeTimer(fakeController);
|
|
}
|
|
|
|
setUp(() {
|
|
timer = PomodoroTimer(
|
|
workMinutes: 1,
|
|
shortBreakMinutes: 1,
|
|
longBreakMinutes: 2,
|
|
pomodorosPerCycle: 4,
|
|
timerFactory: fakeTimerFactory,
|
|
);
|
|
});
|
|
|
|
tearDown(() {
|
|
timer.dispose();
|
|
});
|
|
|
|
Widget createApp() => MaterialApp(
|
|
home: PomodoroScreen(timer: timer),
|
|
);
|
|
|
|
group('PomodoroScreen', () {
|
|
testWidgets('shows initial time', (tester) async {
|
|
await tester.pumpWidget(createApp());
|
|
expect(find.text('01:00'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('shows Work label initially', (tester) async {
|
|
await tester.pumpWidget(createApp());
|
|
expect(find.text('Work'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('shows 0 pomodoros completed', (tester) async {
|
|
await tester.pumpWidget(createApp());
|
|
expect(find.text('0 pomodoros completed'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('play button starts timer', (tester) async {
|
|
await tester.pumpWidget(createApp());
|
|
|
|
// Find and tap the play button.
|
|
final playButton = find.byIcon(Icons.play_arrow);
|
|
expect(playButton, findsOneWidget);
|
|
await tester.tap(playButton);
|
|
await tester.pump();
|
|
|
|
// After ticking, time should decrease.
|
|
fakeController.tick();
|
|
await tester.pump();
|
|
expect(find.text('00:59'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('pause button appears when running', (tester) async {
|
|
await tester.pumpWidget(createApp());
|
|
|
|
await tester.tap(find.byIcon(Icons.play_arrow));
|
|
await tester.pump();
|
|
|
|
expect(find.byIcon(Icons.pause), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('pause button pauses timer', (tester) async {
|
|
await tester.pumpWidget(createApp());
|
|
|
|
// Start.
|
|
await tester.tap(find.byIcon(Icons.play_arrow));
|
|
await tester.pump();
|
|
|
|
fakeController.tick();
|
|
await tester.pump();
|
|
|
|
// Pause.
|
|
await tester.tap(find.byIcon(Icons.pause));
|
|
await tester.pump();
|
|
|
|
expect(find.text('00:59'), findsOneWidget);
|
|
expect(find.byIcon(Icons.play_arrow), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('reset button resets time', (tester) async {
|
|
await tester.pumpWidget(createApp());
|
|
|
|
// Start and tick.
|
|
await tester.tap(find.byIcon(Icons.play_arrow));
|
|
await tester.pump();
|
|
fakeController
|
|
..tick()
|
|
..tick();
|
|
await tester.pump();
|
|
|
|
// Reset.
|
|
await tester.tap(find.byIcon(Icons.refresh));
|
|
await tester.pump();
|
|
|
|
expect(find.text('01:00'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('skip button moves to next mode', (tester) async {
|
|
await tester.pumpWidget(createApp());
|
|
|
|
await tester.tap(find.byIcon(Icons.skip_next));
|
|
await tester.pump();
|
|
|
|
expect(find.text('Short Break'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('shows correct completed count after session', (tester) async {
|
|
await tester.pumpWidget(createApp());
|
|
|
|
// Start and complete a work session.
|
|
await tester.tap(find.byIcon(Icons.play_arrow));
|
|
await tester.pump();
|
|
|
|
for (var i = 0; i < 60; i++) {
|
|
fakeController.tick();
|
|
}
|
|
await tester.pump();
|
|
|
|
expect(find.text('1 pomodoro completed'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('has 4 indicator dots', (tester) async {
|
|
await tester.pumpWidget(createApp());
|
|
|
|
// There should be 4 AnimatedContainers for indicators.
|
|
// We can check that the PomodoroIndicators widget is present.
|
|
expect(find.text('0 pomodoros completed'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('shows style picker with Pomodoro selected', (tester) async {
|
|
await tester.pumpWidget(createApp());
|
|
expect(find.text('Pomodoro'), findsOneWidget);
|
|
expect(find.text('Ultraradian'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('switching to ultraradian updates timer', (tester) async {
|
|
await tester.pumpWidget(createApp());
|
|
|
|
await tester.tap(find.text('Ultraradian'));
|
|
await tester.pump();
|
|
|
|
// Ultraradian work session is 90 minutes.
|
|
expect(find.text('90:00'), findsOneWidget);
|
|
expect(timer.timerStyle, TimerStyle.ultraradian);
|
|
});
|
|
|
|
testWidgets('switching back to pomodoro resets timer', (tester) async {
|
|
await tester.pumpWidget(createApp());
|
|
|
|
await tester.tap(find.text('Ultraradian'));
|
|
await tester.pump();
|
|
expect(find.text('90:00'), findsOneWidget);
|
|
|
|
await tester.tap(find.text('Pomodoro'));
|
|
await tester.pump();
|
|
expect(find.text('25:00'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('onRemoteState delegates to timer', (tester) async {
|
|
await tester.pumpWidget(createApp());
|
|
|
|
final state = tester.state<PomodoroScreenState>(
|
|
find.byType(PomodoroScreen),
|
|
);
|
|
|
|
const remoteState = PomodoroState(
|
|
mode: PomodoroMode.shortBreak,
|
|
remainingSeconds: 200,
|
|
totalSeconds: 300,
|
|
isRunning: false,
|
|
completedPomodoros: 2,
|
|
pomodorosPerCycle: 4,
|
|
);
|
|
|
|
state.onRemoteState(remoteState, 'pause');
|
|
await tester.pump();
|
|
|
|
expect(timer.state.mode, PomodoroMode.shortBreak);
|
|
expect(timer.state.remainingSeconds, 200);
|
|
});
|
|
});
|
|
}
|