142 lines
4.9 KiB
Dart
142 lines
4.9 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:timezone/data/latest.dart' as tzdata;
|
|
import 'package:hepan_everyday/app/app_controller.dart';
|
|
import 'package:hepan_everyday/domain/app_snapshot.dart';
|
|
import 'package:hepan_everyday/domain/app_settings.dart';
|
|
import 'package:hepan_everyday/domain/schedule_engine.dart';
|
|
import 'package:hepan_everyday/features/timetable/timetable_page.dart';
|
|
import 'package:hepan_everyday/widgets/directional_week_transition.dart';
|
|
|
|
import '../support/fakes.dart';
|
|
|
|
AppController _controller({bool hasSemester = true}) {
|
|
Course lesson(int week) => Course(
|
|
id: 'week-$week',
|
|
name: '第$week周课程',
|
|
teacher: '测试教师',
|
|
room: 'A101',
|
|
weekday: 3,
|
|
startPeriod: 1,
|
|
endPeriod: 2,
|
|
weeks: {week},
|
|
source: CourseSource.file,
|
|
);
|
|
return AppController(
|
|
MemoryStore(
|
|
AppSnapshot(
|
|
courses: [lesson(1), lesson(2), lesson(3)],
|
|
settings: AppSettings(
|
|
semester: hasSemester
|
|
? Semester(startDate: DateTime(2026, 10, 12), totalWeeks: 3)
|
|
: null,
|
|
),
|
|
),
|
|
),
|
|
FakeNotifications(),
|
|
FakeCalendar(),
|
|
() => DateTime.utc(2026, 10, 14),
|
|
);
|
|
}
|
|
|
|
Future<void> _open(WidgetTester tester, AppController controller) async {
|
|
await controller.initialize();
|
|
addTearDown(controller.dispose);
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Scaffold(body: TimetablePage(controller: controller)),
|
|
),
|
|
);
|
|
await tester.pumpAndSettle();
|
|
}
|
|
|
|
void main() {
|
|
setUpAll(tzdata.initializeTimeZones);
|
|
testWidgets(
|
|
'week arrows animate the grid and current week reverses direction',
|
|
(tester) async {
|
|
await _open(tester, _controller());
|
|
await tester.tap(find.byIcon(Icons.chevron_right_rounded));
|
|
await tester.pump();
|
|
await tester.pump(const Duration(milliseconds: 100));
|
|
expect(find.byType(DirectionalWeekTransition), findsOneWidget);
|
|
expect(find.text('第1周课程'), findsOneWidget);
|
|
expect(find.text('第2周课程'), findsOneWidget);
|
|
expect(
|
|
tester
|
|
.widget<FractionalTranslation>(
|
|
find.byKey(const Key('week-transition-incoming')),
|
|
)
|
|
.translation
|
|
.dx,
|
|
greaterThan(0),
|
|
);
|
|
await tester.pumpAndSettle();
|
|
expect(find.text('第1周课程'), findsNothing);
|
|
await tester.tap(find.text('本周'));
|
|
await tester.pump();
|
|
await tester.pump(const Duration(milliseconds: 100));
|
|
expect(
|
|
tester
|
|
.widget<FractionalTranslation>(
|
|
find.byKey(const Key('week-transition-incoming')),
|
|
)
|
|
.translation
|
|
.dx,
|
|
lessThan(0),
|
|
);
|
|
await tester.pumpAndSettle();
|
|
expect(find.text('第 1 周'), findsOneWidget);
|
|
expect(find.text('第2周课程'), findsNothing);
|
|
expect(find.text('周日'), findsOneWidget);
|
|
},
|
|
);
|
|
testWidgets(
|
|
'horizontal course swipe changes week and course taps still open',
|
|
(tester) async {
|
|
await _open(tester, _controller());
|
|
expect(find.text('第 1 周'), findsOneWidget);
|
|
expect(find.text('第1周课程'), findsOneWidget);
|
|
await tester.drag(find.text('第1周课程'), const Offset(-180, 0));
|
|
await tester.pumpAndSettle();
|
|
expect(find.text('第 2 周'), findsOneWidget);
|
|
expect(find.text('第1周课程'), findsNothing);
|
|
expect(find.text('第2周课程'), findsOneWidget);
|
|
await tester.tap(find.text('第2周课程'));
|
|
await tester.pumpAndSettle();
|
|
expect(find.text('知道了'), findsOneWidget);
|
|
await tester.tap(find.text('知道了'));
|
|
await tester.pumpAndSettle();
|
|
await tester.drag(find.text('周三'), const Offset(180, 0));
|
|
await tester.pumpAndSettle();
|
|
expect(find.text('第 1 周'), findsOneWidget);
|
|
},
|
|
);
|
|
testWidgets('one swipe advances one week and stops at semester boundaries', (
|
|
tester,
|
|
) async {
|
|
await _open(tester, _controller());
|
|
await tester.drag(find.text('周三'), const Offset(300, 0));
|
|
await tester.pumpAndSettle();
|
|
expect(find.text('第 1 周'), findsOneWidget);
|
|
for (final week in [2, 3, 3]) {
|
|
await tester.drag(find.text('周三'), const Offset(-300, 0));
|
|
await tester.pumpAndSettle();
|
|
expect(find.text('第 $week 周'), findsOneWidget);
|
|
}
|
|
await tester.tap(find.text('本周'));
|
|
await tester.pumpAndSettle();
|
|
expect(find.text('第 1 周'), findsOneWidget);
|
|
});
|
|
testWidgets('swiping an imported timetable without a semester keeps prompt', (
|
|
tester,
|
|
) async {
|
|
await _open(tester, _controller(hasSemester: false));
|
|
await tester.drag(find.byType(TimetablePage), const Offset(-180, 0));
|
|
await tester.pumpAndSettle();
|
|
expect(find.text('课表已导入,请设置学期开始日'), findsOneWidget);
|
|
expect(find.text('第 2 周'), findsNothing);
|
|
expect(tester.takeException(), isNull);
|
|
});
|
|
}
|