feat: 实现起卦、设置与积分系统

This commit is contained in:
qzl
2026-04-03 16:56:47 +08:00
parent 31594558eb
commit f245eec5f6
170 changed files with 20728 additions and 328 deletions
@@ -0,0 +1,46 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:meeyao_qianwen/features/divination/data/models/divination_params.dart';
void main() {
test('mock data contains valid defaults', () {
final params = DivinationMockData.initial();
expect(params.method, DivinationMethod.manual);
expect(params.questionType, QuestionType.career);
expect(params.coinBalance, greaterThan(0));
expect(params.userId, isNotEmpty);
});
test('toPayload returns normalized payload map', () {
final params = DivinationParams(
method: DivinationMethod.auto,
questionType: QuestionType.health,
question: '最近体检是否顺利',
divinationTime: DateTime(2026, 4, 3, 10, 30),
coinBalance: 6,
userId: 'mock_2',
);
final payload = params.toPayload();
expect(payload['method'], 'auto');
expect(payload['questionType'], 'health');
expect(payload['question'], '最近体检是否顺利');
expect(payload['coinBalance'], 6);
expect(payload['userId'], 'mock_2');
});
test('toBinary and toChangedBinary mappings are correct', () {
final params = DivinationMockData.initial();
final states = <YaoType>[
YaoType.oldYin,
YaoType.youngYang,
YaoType.youngYin,
YaoType.oldYang,
YaoType.youngYang,
YaoType.oldYin,
];
expect(params.toBinary(states), '010110');
expect(params.toChangedBinary(states), '110011');
});
}
@@ -0,0 +1,36 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:meeyao_qianwen/features/divination/data/models/divination_params.dart';
import 'package:meeyao_qianwen/features/divination/data/services/divination_result_builder.dart';
void main() {
final builder = DivinationResultBuilder();
test('build returns result with hexagram names and section text', () {
final params = DivinationMockData.initial().copyWith(
method: DivinationMethod.auto,
question: '近期工作是否会有突破',
questionType: QuestionType.career,
);
final result = builder.build(
params: params,
yaoStates: const [
YaoType.youngYang,
YaoType.youngYin,
YaoType.oldYang,
YaoType.youngYin,
YaoType.oldYin,
YaoType.youngYang,
],
);
expect(result.guaName, isNotEmpty);
expect(result.targetGuaName, isNotEmpty);
expect(result.binaryCode, hasLength(6));
expect(result.changedBinaryCode, hasLength(6));
expect(result.keywords, contains(''));
expect(result.conclusion, contains('这个卦象的结果为'));
expect(result.yaoLines.length, 6);
expect(result.targetYaoLines.length, 6);
});
}
@@ -0,0 +1,52 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:meeyao_qianwen/app/app_theme.dart';
import 'package:meeyao_qianwen/features/divination/data/models/divination_params.dart';
import 'package:meeyao_qianwen/features/divination/data/services/divination_result_builder.dart';
import 'package:meeyao_qianwen/features/divination/presentation/screens/divination_result_screen.dart';
void main() {
testWidgets('result screen shows key sections', (tester) async {
final params = DivinationMockData.initial().copyWith(
method: DivinationMethod.auto,
questionType: QuestionType.health,
question: '近期状态是否平稳',
);
final data = DivinationResultBuilder().build(
params: params,
yaoStates: const [
YaoType.oldYin,
YaoType.youngYang,
YaoType.youngYin,
YaoType.oldYang,
YaoType.youngYang,
YaoType.oldYin,
],
);
await tester.pumpWidget(
MaterialApp(
theme: AppTheme.light(),
home: DivinationResultScreen(data: data),
),
);
await tester.pump();
expect(find.text('天机推演中'), findsOneWidget);
await tester.pump(const Duration(milliseconds: 450));
expect(find.text('正在解卦'), findsOneWidget);
await tester.pump(const Duration(milliseconds: 850));
expect(find.text('解卦完成\n点击查看'), findsOneWidget);
expect(find.text('解卦结果'), findsOneWidget);
expect(find.text('AI解卦'), findsOneWidget);
expect(find.text('基础信息'), findsOneWidget);
expect(find.text('卦象详情'), findsOneWidget);
expect(find.text('解卦结论'), findsOneWidget);
expect(find.text('○ 老阳(变)'), findsOneWidget);
expect(find.text('× 老阴(变)'), findsOneWidget);
expect(find.text(''), findsWidgets);
expect(find.text('×'), findsWidgets);
});
}
@@ -0,0 +1,62 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:meeyao_qianwen/app/app_theme.dart';
import 'package:meeyao_qianwen/features/divination/data/models/divination_params.dart';
import 'package:meeyao_qianwen/features/divination/presentation/screens/auto_divination_screen.dart';
import 'package:meeyao_qianwen/features/divination/presentation/screens/divination_screen.dart';
import 'package:meeyao_qianwen/features/divination/presentation/screens/manual_divination_screen.dart';
void main() {
testWidgets('divination screen navigates to auto screen', (tester) async {
await tester.pumpWidget(
MaterialApp(theme: AppTheme.light(), home: const DivinationScreen()),
);
await tester.tap(find.text('自动起卦'));
await tester.enterText(find.byType(TextField), '最近事业发展是否顺利');
await tester.tap(find.text('开始起卦'));
await tester.pumpAndSettle();
expect(find.byType(AutoDivinationScreen), findsOneWidget);
expect(find.text('○ 老阳(变)'), findsOneWidget);
expect(find.text('× 老阴(变)'), findsOneWidget);
});
testWidgets('auto screen keeps resolve button disabled initially', (
tester,
) async {
final params = DivinationMockData.initial().copyWith(
method: DivinationMethod.auto,
question: '测试问题',
);
await tester.pumpWidget(
MaterialApp(
theme: AppTheme.light(),
home: AutoDivinationScreen(params: params),
),
);
final resolveButton = tester.widget<FilledButton>(
find.widgetWithText(FilledButton, '开始解卦'),
);
expect(resolveButton.onPressed, isNull);
expect(find.text('您还需摇 6 次'), findsOneWidget);
});
testWidgets('divination screen navigates to manual screen by default', (
tester,
) async {
await tester.pumpWidget(
MaterialApp(theme: AppTheme.light(), home: const DivinationScreen()),
);
await tester.enterText(find.byType(TextField), '近期感情是否稳定');
await tester.tap(find.text('开始起卦'));
await tester.pump();
await tester.pump(const Duration(milliseconds: 300));
expect(find.byType(ManualDivinationScreen), findsOneWidget);
});
}
@@ -0,0 +1,26 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:meeyao_qianwen/app/app_theme.dart';
import 'package:meeyao_qianwen/features/divination/data/models/divination_params.dart';
import 'package:meeyao_qianwen/features/divination/presentation/screens/manual_divination_screen.dart';
void main() {
testWidgets('manual screen shows yao legend', (tester) async {
final params = DivinationMockData.initial().copyWith(
method: DivinationMethod.manual,
question: '测试问题',
);
await tester.pumpWidget(
MaterialApp(
theme: AppTheme.light(),
home: ManualDivinationScreen(params: params),
),
);
expect(find.text('○ 老阳(变)'), findsOneWidget);
expect(find.text('× 老阴(变)'), findsOneWidget);
expect(find.text('初爻'), findsOneWidget);
expect(find.text('上爻'), findsOneWidget);
});
}