Files
Ichino/test/rating_calculator_test.dart
T
Cookiues 79fa0d7a20 feat: 移植 B50 成绩图,并把项目名从 purarine 改回 ichino
海报从 Empurple 的 Best50ImageRenderer/ImageBuilder 移植:按原始像素坐标
(1762x1850 画布、300x100 卡片、5 列、行距 120) 叠加在 base.png 上,底图里
已画好的面板/药丸标签/页脚不重复绘制;页面外壳走 Ichino 的 Material 3。

RatingCalculator 的达成率分档改成单张有序表,避免偏移与评级错位;
RA 与评级由 test/rating_calculator_test.dart 的边界用例锁定。

GetUserRatingApi 只需要 userId(Cookie 可选),所以 Preview API 模式、未登录
游戏服务器时也能出图,只是没有 FC/AP/FS 标记。导出用 RepaintBoundary 抓
全尺寸 PNG:原生走 share_plus(不支持文件分享的平台回退为落盘并提示路径),
web 走下载。

BEST35 与 BEST15 改为各自独立排版。原先沿用 Empurple 的跨列表全局序号,
BEST35 没打满时 BEST15 会整体上移混进上半区。

path_provider 会经 path_provider_android 2.3.x 拖入 jni 插件,而 jni 把
windows/linux 也声明成 ffiPlugin,桌面构建因此去链接 jvm.lib 并失败,
故用 dependency_overrides 钉住 path_provider_android <2.3.0。
2026-09-25 22:25:35 +08:00

81 lines
2.1 KiB
Dart

import 'package:flutter_test/flutter_test.dart';
import 'package:ichino/services/rating_calculator.dart';
/// achievementRaw 接口原值(百分比 * 10000)。
double _pct(int raw) => raw / 10000.0;
void main() {
group('评级区间边界', () {
const cases = <int, String>{
0: 'D',
99999: 'D',
100000: 'D',
499999: 'D',
500000: 'C',
599999: 'C',
600000: 'B',
699999: 'B',
700000: 'BB',
749999: 'BB',
750000: 'BBB',
799999: 'BBB',
800000: 'A',
899999: 'A',
900000: 'AA',
939999: 'AA',
940000: 'AAA',
969999: 'AAA',
970000: 'S',
979999: 'S',
980000: 'Sp',
989999: 'Sp',
990000: 'SS',
994999: 'SS',
995000: 'SSp',
999999: 'SSp',
1000000: 'SSS',
1004999: 'SSS',
1005000: 'SSSp',
};
cases.forEach((raw, expected) {
test('$raw => $expected', () {
expect(RatingCalculator.compute(10.0, _pct(raw)).rate, expected);
});
});
});
group('RA 计算', () {
test('低于 10% 时 RA 为 0', () {
expect(RatingCalculator.computeRa(10.0, _pct(99999)), 0);
});
test('ds 10.0 / 100.1234% => 216', () {
expect(RatingCalculator.compute(10.0, _pct(1001234)).ra, 216);
});
test('ds 10.0 / 99.0000% => 205 (整数截断)', () {
expect(RatingCalculator.compute(10.0, _pct(990000)).ra, 205);
});
test('ds 10.0 / 100.5% 封顶 SSSp => 225', () {
expect(RatingCalculator.compute(10.0, _pct(1005000)).ra, 225);
});
test('超出 100.5% 的达成率被夹到上限', () {
final clamped = RatingCalculator.compute(10.0, _pct(1200000));
final capped = RatingCalculator.compute(10.0, _pct(1005000));
expect(clamped.ra, capped.ra);
expect(clamped.rate, capped.rate);
});
test('定数 13.0 / 100% => 280', () {
expect(RatingCalculator.compute(13.0, _pct(1000000)).ra, 280);
});
test('缺失定数 (ds=0) 时 RA 为 0', () {
expect(RatingCalculator.computeRa(0.0, _pct(1005000)), 0);
});
});
}