- 添加官方 AGPL-3.0 全文 - LICENSE 作为 asset 打包,注册进 Flutter 许可清单 - 关于页「开源许可」改为打开许可页 - README 补充简介、开发命令与许可说明
195 lines
6.7 KiB
Dart
195 lines
6.7 KiB
Dart
import 'package:flutter/material.dart';
|
||
import 'package:flutter_test/flutter_test.dart';
|
||
|
||
import 'package:mobile/main.dart';
|
||
import 'package:mobile/widgets/grouped_list_section.dart';
|
||
|
||
/// 在导航栏内按标签定位,避免和页面标题的相同文字混淆。
|
||
Finder navLabel(String label) {
|
||
return find.descendant(
|
||
of: find.byType(NavigationBar),
|
||
matching: find.text(label),
|
||
);
|
||
}
|
||
|
||
/// 手机尺寸(400 × 800 dp),避免默认 800×600 掩盖溢出问题。
|
||
void usePhoneSurface(WidgetTester tester) {
|
||
tester.view.physicalSize = const Size(400, 800);
|
||
tester.view.devicePixelRatio = 1.0;
|
||
addTearDown(tester.view.reset);
|
||
}
|
||
|
||
Future<void> pumpApp(WidgetTester tester) async {
|
||
usePhoneSurface(tester);
|
||
await tester.pumpWidget(const KiriMemoApp());
|
||
await tester.pumpAndSettle();
|
||
}
|
||
|
||
void main() {
|
||
testWidgets('底部导航提供学习 / 管理 / 统计 / 账户四个入口', (WidgetTester tester) async {
|
||
await pumpApp(tester);
|
||
|
||
expect(find.byType(NavigationBar), findsOneWidget);
|
||
expect(find.byType(NavigationDestination), findsNWidgets(4));
|
||
|
||
for (final String label in <String>['学习', '管理', '统计', '账户']) {
|
||
expect(navLabel(label), findsOneWidget);
|
||
}
|
||
});
|
||
|
||
testWidgets('Android 端使用水平滑入转场,而非预测式返回', (WidgetTester tester) async {
|
||
await pumpApp(tester);
|
||
|
||
final MaterialApp app = tester.widget<MaterialApp>(find.byType(MaterialApp));
|
||
final PageTransitionsTheme transitions = app.theme!.pageTransitionsTheme;
|
||
expect(
|
||
transitions.builders[TargetPlatform.android],
|
||
isA<FadeForwardsPageTransitionsBuilder>(),
|
||
);
|
||
});
|
||
|
||
testWidgets('默认停留在学习页,点击其它入口会切换', (WidgetTester tester) async {
|
||
await pumpApp(tester);
|
||
|
||
NavigationBar bar = tester.widget<NavigationBar>(find.byType(NavigationBar));
|
||
expect(bar.selectedIndex, 0);
|
||
|
||
await tester.tap(navLabel('统计'));
|
||
await tester.pumpAndSettle();
|
||
|
||
bar = tester.widget<NavigationBar>(find.byType(NavigationBar));
|
||
expect(bar.selectedIndex, 2);
|
||
|
||
await tester.tap(navLabel('账户'));
|
||
await tester.pumpAndSettle();
|
||
|
||
bar = tester.widget<NavigationBar>(find.byType(NavigationBar));
|
||
expect(bar.selectedIndex, 3);
|
||
});
|
||
|
||
testWidgets('学习首页展示今日任务与唯一主行动', (WidgetTester tester) async {
|
||
await pumpApp(tester);
|
||
|
||
expect(find.text('今日计划'), findsOneWidget);
|
||
expect(find.text('待复习'), findsOneWidget);
|
||
expect(find.text('待新识'), findsOneWidget);
|
||
expect(find.text('开始学习'), findsOneWidget);
|
||
|
||
// 顶部状态标识:接力用闪电、同步用云图标,不再用文字表达状态。
|
||
expect(find.byIcon(Icons.bolt_rounded), findsOneWidget);
|
||
expect(find.text('今日记忆'), findsOneWidget);
|
||
expect(find.text('59'), findsOneWidget);
|
||
expect(find.byIcon(Icons.cloud_done_rounded), findsOneWidget);
|
||
expect(find.byTooltip('搜索条目'), findsOneWidget);
|
||
expect(find.byTooltip('学习日志'), findsOneWidget);
|
||
|
||
// 学习域的四个快捷入口。
|
||
for (final String label in <String>['收藏夹', '自我测试', '附带资料', '计划设置']) {
|
||
expect(find.text(label), findsOneWidget);
|
||
}
|
||
});
|
||
|
||
testWidgets('未接入内核的入口点击后给出反馈', (WidgetTester tester) async {
|
||
await pumpApp(tester);
|
||
|
||
await tester.tap(find.text('开始学习'));
|
||
await tester.pump();
|
||
await tester.pump(const Duration(milliseconds: 300));
|
||
|
||
expect(find.text('学习会话 尚未接入内核'), findsOneWidget);
|
||
});
|
||
|
||
testWidgets('管理页有三个维度,各自列出卡片', (WidgetTester tester) async {
|
||
await pumpApp(tester);
|
||
await tester.tap(navLabel('管理'));
|
||
await tester.pumpAndSettle();
|
||
|
||
for (final String label in <String>['单元集', '计划', '算法']) {
|
||
expect(find.text(label), findsOneWidget);
|
||
}
|
||
expect(find.text('高考必背古诗文'), findsOneWidget);
|
||
expect(find.text('标识 cngk-t'), findsOneWidget);
|
||
|
||
await tester.tap(find.text('计划'));
|
||
await tester.pumpAndSettle();
|
||
expect(find.text('每日计划'), findsOneWidget);
|
||
expect(find.text('周末冲刺'), findsOneWidget);
|
||
expect(find.text('新识记'), findsNWidgets(2));
|
||
|
||
await tester.tap(find.text('算法'));
|
||
await tester.pumpAndSettle();
|
||
expect(find.text('NSP-0'), findsOneWidget);
|
||
expect(find.text('默认'), findsOneWidget);
|
||
});
|
||
|
||
testWidgets('账户页展示资料、学习数据与四个功能入口', (WidgetTester tester) async {
|
||
await pumpApp(tester);
|
||
await tester.tap(navLabel('账户'));
|
||
await tester.pumpAndSettle();
|
||
|
||
expect(find.text('zhiyu'), findsOneWidget);
|
||
expect(find.text('ID KM-1024 · 大一'), findsOneWidget);
|
||
expect(find.text('累计学习'), findsOneWidget);
|
||
expect(find.text('坚持'), findsOneWidget);
|
||
|
||
// 四个入口是同一张分组卡片里的四行。
|
||
expect(find.byType(GroupedListSection), findsOneWidget);
|
||
expect(find.byType(GroupedListTile), findsNWidgets(4));
|
||
|
||
for (final String label in <String>[
|
||
'设置',
|
||
'文档与帮助',
|
||
'反馈问题',
|
||
'关于 KiriMemo',
|
||
]) {
|
||
expect(find.text(label), findsOneWidget);
|
||
}
|
||
});
|
||
|
||
testWidgets('账户页可以进入设置页,设置项按分组排列', (WidgetTester tester) async {
|
||
await pumpApp(tester);
|
||
await tester.tap(navLabel('账户'));
|
||
await tester.pumpAndSettle();
|
||
|
||
await tester.tap(find.text('设置'));
|
||
await tester.pumpAndSettle();
|
||
|
||
expect(find.text('每日新识记上限'), findsOneWidget);
|
||
expect(find.text('答错后重新排队'), findsOneWidget);
|
||
|
||
// 分组在下方,需要滚动到可见。
|
||
await tester.scrollUntilVisible(find.text('版本'), 200);
|
||
expect(find.text('版本'), findsOneWidget);
|
||
expect(find.text('1.0.0'), findsOneWidget);
|
||
});
|
||
|
||
testWidgets('关于页声明 AGPL-3.0 授权', (WidgetTester tester) async {
|
||
await pumpApp(tester);
|
||
await tester.tap(navLabel('账户'));
|
||
await tester.pumpAndSettle();
|
||
|
||
await tester.tap(find.text('关于 KiriMemo'));
|
||
await tester.pumpAndSettle();
|
||
|
||
expect(find.text('GNU AGPL v3.0'), findsOneWidget);
|
||
});
|
||
|
||
testWidgets('文档与帮助页底部有可上滑的助手', (WidgetTester tester) async {
|
||
await pumpApp(tester);
|
||
await tester.tap(navLabel('账户'));
|
||
await tester.pumpAndSettle();
|
||
|
||
await tester.tap(find.text('文档与帮助'));
|
||
await tester.pumpAndSettle();
|
||
|
||
expect(find.text('文档内容将在这里显示'), findsOneWidget);
|
||
expect(find.text('问问 KiriMemo'), findsOneWidget);
|
||
|
||
// 收起时是横栏,点开后出现输入框。
|
||
expect(find.byType(TextField), findsNothing);
|
||
await tester.tap(find.text('问问 KiriMemo'));
|
||
await tester.pumpAndSettle();
|
||
expect(find.byType(TextField), findsOneWidget);
|
||
});
|
||
}
|