Files
TPSchedule/mobile/test/widgets/glass_dock_test.dart
T

156 lines
5.4 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:hepan_everyday/widgets/glass_dock.dart';
import 'package:hepan_everyday/widgets/tab_deck.dart';
import 'package:hepan_everyday/app/hepan_app.dart';
import 'package:hepan_everyday/features/timetable/timetable_page.dart';
import 'package:timezone/data/latest.dart' as tzdata;
import 'navigation_test.dart' show uiController;
void main() {
setUpAll(tzdata.initializeTimeZones);
testWidgets(
'tab content finishes within one frame of 240ms and retains page state',
(tester) async {
Widget deck(int index) => MaterialApp(
home: Scaffold(
body: TabDeck(
index: index,
children: const [TextField(), Text('新页面')],
),
),
);
await tester.pumpWidget(deck(0));
await tester.enterText(find.byType(TextField), '保留内容');
FocusManager.instance.primaryFocus?.unfocus();
await tester.pumpWidget(deck(1));
await tester.pump(); // Start the transition clock before advancing it.
await tester.pump(const Duration(milliseconds: 240));
await tester.pump(const Duration(milliseconds: 16));
expect(find.byType(TextField), findsNothing);
expect(find.text('新页面'), findsOneWidget);
await tester.pumpWidget(deck(0));
await tester.pumpAndSettle();
expect(find.text('保留内容'), findsOneWidget);
},
);
testWidgets('only the selected tab is blue, including during glass travel', (
tester,
) async {
var selected = 0;
await tester.pumpWidget(
MaterialApp(
home: StatefulBuilder(
builder: (context, setState) => Scaffold(
body: Center(
child: GlassDock(
selectedIndex: selected,
onSelected: (index) => setState(() => selected = index),
),
),
),
),
),
);
Color colour(IconData icon) =>
tester.widget<Icon>(find.byIcon(icon)).color!;
void expectGrey(IconData icon) {
final value = colour(icon);
expect((value.r - value.b).abs(), lessThan(0.12));
expect(value.a, 1);
}
expect(colour(Icons.calendar_month_rounded), const Color(0xFF007AFF));
expectGrey(Icons.assignment_rounded);
expectGrey(Icons.person_rounded);
await tester.tap(find.byIcon(Icons.person_rounded));
await tester.pump();
// Colour follows the selected page, not whichever icon the lens crosses.
expect(colour(Icons.person_rounded), const Color(0xFF007AFF));
expectGrey(Icons.calendar_month_rounded);
await tester.pump(const Duration(milliseconds: 100));
expectGrey(Icons.assignment_rounded);
await tester.pumpAndSettle();
final gesture = await tester.startGesture(
tester.getCenter(find.byKey(const Key('dock-cursor'))),
);
await gesture.moveBy(const Offset(-20, 0));
await tester.pump();
await gesture.moveBy(const Offset(-90, 0));
await tester.pump(const Duration(milliseconds: 150));
expect(colour(Icons.person_rounded), const Color(0xFF007AFF));
expectGrey(Icons.assignment_rounded);
await gesture.up();
await tester.pumpAndSettle();
expect(selected, 1);
expect(colour(Icons.assignment_rounded), const Color(0xFF007AFF));
expectGrey(Icons.person_rounded);
});
testWidgets('dock drags switch tabs while body swipes only change week', (
tester,
) async {
final c = uiController();
await c.initialize();
await c.showDemo();
await tester.pumpWidget(HepanApp(controller: c));
await tester.pumpAndSettle();
expect(
find.descendant(
of: find.byType(TimetablePage),
matching: find.text('课表'),
),
findsOneWidget,
);
expect(tester.getRect(find.text('周日')).right, lessThanOrEqualTo(800));
await tester.drag(find.text('周三'), const Offset(-250, 0));
await tester.pumpAndSettle();
expect(find.text('第 2 周'), findsOneWidget);
expect(find.text('选择学校'), findsNothing);
await tester.drag(
find.byKey(const Key('dock-cursor')),
const Offset(185, 0),
);
await tester.pumpAndSettle();
expect(find.text('选择学校'), findsOneWidget);
await tester.drag(find.text('学校课表'), const Offset(250, 0));
await tester.pumpAndSettle();
expect(find.text('选择学校'), findsOneWidget);
await tester.drag(
find.byKey(const Key('dock-cursor')),
const Offset(-185, 0),
);
await tester.pumpAndSettle();
expect(find.text('示例课表'), findsOneWidget);
await tester.tap(find.text('我的'));
await tester.pumpAndSettle();
expect(find.text('选择学校'), findsOneWidget);
c.dispose();
});
testWidgets('cancelled cursor drag keeps selected tab', (tester) async {
int selected = 0;
await tester.pumpWidget(
MaterialApp(
home: StatefulBuilder(
builder: (context, setState) => Scaffold(
body: Center(
child: GlassDock(
selectedIndex: selected,
onSelected: (i) => setState(() => selected = i),
),
),
),
),
),
);
final gesture = await tester.startGesture(
tester.getCenter(find.byKey(const Key('dock-cursor'))),
);
await gesture.moveBy(const Offset(90, 0));
await tester.pump();
await gesture.cancel();
await tester.pumpAndSettle();
expect(selected, 0);
});
}