125 lines
4.1 KiB
Dart
125 lines
4.1 KiB
Dart
import 'package:flutter/material.dart';
|
||
import 'package:flutter/rendering.dart';
|
||
import 'package:flutter_test/flutter_test.dart';
|
||
import 'package:timezone/data/latest.dart' as tzdata;
|
||
import 'package:hepan_everyday/features/timetable/week_grid.dart';
|
||
import 'package:hepan_everyday/domain/schedule_engine.dart';
|
||
import 'package:hepan_everyday/domain/app_settings.dart';
|
||
|
||
void main() {
|
||
setUpAll(tzdata.initializeTimeZones);
|
||
testWidgets(
|
||
'conflicts keep readable full-width metadata without covering courses',
|
||
(tester) async {
|
||
tester.view.physicalSize = const Size(320, 800);
|
||
tester.view.devicePixelRatio = 1;
|
||
addTearDown(tester.view.resetPhysicalSize);
|
||
addTearDown(tester.view.resetDevicePixelRatio);
|
||
final term = Semester(startDate: DateTime(2026, 9, 7), totalWeeks: 1);
|
||
final courses = List.generate(
|
||
5,
|
||
(i) => Course(
|
||
id: '$i',
|
||
name: '并行课程$i',
|
||
teacher: '示例教师$i',
|
||
room: '示例教学楼B10$i',
|
||
weekday: 1,
|
||
startPeriod: 1,
|
||
endPeriod: 2,
|
||
weeks: {1},
|
||
source: CourseSource.file,
|
||
),
|
||
);
|
||
final events = ScheduleEngine.occurrences(courses, term);
|
||
await tester.pumpWidget(
|
||
MaterialApp(
|
||
home: MediaQuery(
|
||
data: MediaQueryData(textScaler: TextScaler.linear(2)),
|
||
child: Scaffold(
|
||
body: SingleChildScrollView(
|
||
child: WeekGrid(
|
||
events: events,
|
||
monday: term.firstMonday,
|
||
today: term.startDate,
|
||
settings: const AppSettings(),
|
||
),
|
||
),
|
||
),
|
||
),
|
||
),
|
||
);
|
||
await tester.pumpAndSettle();
|
||
expect(find.text('冲突列表'), findsOneWidget);
|
||
expect(find.text('1–2节'), findsNWidgets(5));
|
||
final rects = <Rect>[];
|
||
for (final c in courses) {
|
||
final card = tester.getRect(
|
||
find.bySemanticsLabel('${c.name},${c.teacher},${c.room}'),
|
||
);
|
||
rects.add(card);
|
||
expect(card.width, greaterThan(30));
|
||
for (final text in [c.teacher, c.room]) {
|
||
final finder = find.text(text);
|
||
final paragraph = tester.renderObject<RenderParagraph>(finder);
|
||
for (final box in paragraph.getBoxesForSelection(
|
||
TextSelection(baseOffset: 0, extentOffset: text.length),
|
||
)) {
|
||
expect(box.right, lessThanOrEqualTo(paragraph.size.width + 0.01));
|
||
}
|
||
expect(tester.getRect(finder).bottom, lessThanOrEqualTo(card.bottom));
|
||
}
|
||
}
|
||
for (var i = 0; i < rects.length; i++) {
|
||
for (var j = i + 1; j < rects.length; j++) {
|
||
expect(
|
||
rects[i].intersect(rects[j]).height,
|
||
lessThanOrEqualTo(0.01),
|
||
reason: '${rects[i]} / ${rects[j]}',
|
||
);
|
||
}
|
||
}
|
||
expect(tester.takeException(), isNull);
|
||
},
|
||
);
|
||
testWidgets(
|
||
'a lunch-gap arrangement has the same length as another two-lesson card',
|
||
(tester) async {
|
||
final term = Semester(startDate: DateTime(2026, 9, 7), totalWeeks: 1);
|
||
Course c(String id, int day, int first) => Course(
|
||
id: id,
|
||
name: id,
|
||
teacher: '教师',
|
||
room: '教室',
|
||
weekday: day,
|
||
startPeriod: first,
|
||
endPeriod: first + 1,
|
||
weeks: {1},
|
||
source: CourseSource.file,
|
||
);
|
||
final events = ScheduleEngine.occurrences([
|
||
c('A', 1, 3),
|
||
c('B', 2, 4),
|
||
], term);
|
||
await tester.pumpWidget(
|
||
MaterialApp(
|
||
home: Scaffold(
|
||
body: SingleChildScrollView(
|
||
child: WeekGrid(
|
||
events: events,
|
||
monday: term.firstMonday,
|
||
today: term.startDate,
|
||
settings: const AppSettings(),
|
||
),
|
||
),
|
||
),
|
||
),
|
||
);
|
||
await tester.pumpAndSettle();
|
||
expect(
|
||
tester.getRect(find.bySemanticsLabel('A,教师,教室')).height,
|
||
tester.getRect(find.bySemanticsLabel('B,教师,教室')).height,
|
||
);
|
||
},
|
||
);
|
||
}
|