import 'package:flutter_test/flutter_test.dart'; import 'package:qiangbao_accounting/models/account.dart'; void main() { group('余额反算 initialBalanceFor', () { // 后端公式:balance = initialBalance + totalIncome - totalExpense test('无收支时目标余额就是期初余额', () { expect( initialBalanceFor(targetBalance: 5000, totalIncome: 0, totalExpense: 0), 5000, ); }); test('有收入时需扣除收入', () { // 收入 8000,想让余额显示 5000 → 期初 = 5000 - 8000 = -3000 expect( initialBalanceFor(targetBalance: 5000, totalIncome: 8000, totalExpense: 0), -3000, ); }); test('有支出时需加回支出', () { // 支出 1200,想让余额显示 5000 → 期初 = 5000 + 1200 = 6200 expect( initialBalanceFor(targetBalance: 5000, totalIncome: 0, totalExpense: 1200), 6200, ); }); test('收支都有时综合换算', () { // 收 8000 支 1200,目标 5000 → 5000 - 8000 + 1200 = -1800 expect( initialBalanceFor(targetBalance: 5000, totalIncome: 8000, totalExpense: 1200), -1800, ); }); test('换算后余额能被后端公式还原(往返一致)', () { const target = 12345.67; const income = 8000.0; const expense = 3456.78; final initial = initialBalanceFor( targetBalance: target, totalIncome: income, totalExpense: expense, ); // 模拟后端计算 final balance = initial + income - expense; expect(balance, closeTo(target, 0.001)); }); test('目标余额非法时返回 0', () { expect( initialBalanceFor(targetBalance: double.nan, totalIncome: 100, totalExpense: 0), 0, ); expect( initialBalanceFor(targetBalance: double.infinity, totalIncome: 0, totalExpense: 0), 0, ); }); }); group('AccountInfo.fromJson 防御性', () { test('字段缺失时不抛异常并按公式兜底算余额', () { final a = AccountInfo.fromJson({ 'id': '3', 'initialBalance': '1000', 'totalIncome': 500, 'totalExpense': '200.5', // name / balance 缺失 }); expect(a.id, 3); expect(a.name, '默认账户'); expect(a.initialBalance, 1000); expect(a.totalIncome, 500); expect(a.totalExpense, 200.5); expect(a.balance, 1000 + 500 - 200.5); // 本地兜底计算 }); test('后端给了 balance 时优先使用后端值', () { final a = AccountInfo.fromJson({ 'initialBalance': 1000, 'totalIncome': 500, 'totalExpense': 200, 'balance': 9999, // 故意与公式不一致 }); expect(a.balance, 9999); }); test('完全空对象返回零值账户', () { final a = AccountInfo.fromJson({}); expect(a.balance, 0); expect(a.totalIncome, 0); expect(a.totalExpense, 0); }); }); }