mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-10 20:07:04 +01:00
Brings the repo to prettier-clean across all 525 tracked md/json/yaml files. The markdown edits are cosmetic: escaping `L*` so it stops rendering as emphasis, normalising `*em*` to `_em_`, and aligning tables. billsplit/android/gradle.properties shipped from the Flutter template asking for `-Xmx8G -XX:MaxMetaspaceSize=4G` — more than this machine has. Lowered to 768m/512m and, more importantly, cut the number of JVMs: Kotlin compiles in-process, no persistent daemon, no parallel execution, one worker. Also repairs a regression an earlier prettier pass introduced. That pass pretty-printed test/fixtures/sample_receipt.json, but `accepts bare JPK payload and bare JWS token` reads the fixture as raw TEXT with a regex matching `"data":"..."` with no space after the colon. The inserted space made the match null and the null-check operator threw. Comparing the parsed JSON for equality had passed and proved nothing about that raw-text contract. The fixture is restored to its original minified bytes — a real e-paragon arrives as single-line JSON — and test/fixtures/ is now in .prettierignore so captured payloads stay byte-faithful. The regex also tolerates whitespace now and asserts the match is non-null with a reason, so the same change would fail readably instead of crashing. Verified against both the minified and the pretty-printed fixture. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
87 lines
3.1 KiB
Dart
87 lines
3.1 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:billsplit/domain/eparagon_parser.dart';
|
|
import 'package:billsplit/domain/models.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
void main() {
|
|
final fixture = File('test/fixtures/sample_receipt.json').readAsStringSync();
|
|
|
|
test('parses the real Biedronka e-paragon wrapper', () {
|
|
final res = parseEParagonDetailed(fixture);
|
|
final r = res.receipt;
|
|
|
|
// 49 goods lines + 1 deposit line.
|
|
expect(r.items.length, 50);
|
|
final deposit =
|
|
r.items.where((i) => i.category == Categories.deposit).toList();
|
|
expect(deposit.length, 1);
|
|
expect(deposit.single.totalGr, 700);
|
|
expect(deposit.single.qty, 14);
|
|
|
|
// Goods sum matches receipt sumaBrutto; paid total includes deposit.
|
|
final goods = r.items
|
|
.where((i) => i.category != Categories.deposit)
|
|
.fold(0, (s, i) => s + i.totalGr);
|
|
expect(goods, 59055);
|
|
expect(r.paidTotalGr, 59755);
|
|
expect(res.warnings, isEmpty);
|
|
|
|
// Alcohol detection: exactly vodka + beer, drinkers-only by default.
|
|
final alcohol =
|
|
r.items.where((i) => i.category == Categories.alcohol).toList();
|
|
expect(alcohol.length, 2);
|
|
expect(
|
|
alcohol.map((i) => i.name).join(' | ').toLowerCase(),
|
|
allOf(contains('wódka'), contains('piwo')),
|
|
);
|
|
for (final a in alcohol) {
|
|
expect(a.assignment.mode, AssignMode.drinkers);
|
|
}
|
|
expect(alcohol.fold(0, (s, i) => s + i.totalGr), 10872);
|
|
|
|
// Mixers tagged but split among everyone.
|
|
final mixers =
|
|
r.items.where((i) => i.category == Categories.mixer).toList();
|
|
expect(mixers.length, greaterThanOrEqualTo(4));
|
|
for (final m in mixers) {
|
|
expect(m.assignment.mode, AssignMode.everyone);
|
|
}
|
|
|
|
// Name cleanup: VAT letter stripped, spaces collapsed.
|
|
expect(r.items.first.name, 'Tonic');
|
|
// Weight-based quantity with comma decimal.
|
|
final kielbasa =
|
|
r.items.firstWhere((i) => i.name.startsWith('KiełbBrocka'));
|
|
expect(kielbasa.qty, closeTo(0.871, 1e-9));
|
|
// Discount captured (vodka -28.00).
|
|
final vodka = r.items.firstWhere((i) => i.name.startsWith('WódkaB'));
|
|
expect(vodka.discountGr, -2800);
|
|
expect(vodka.totalGr, 7998);
|
|
});
|
|
|
|
test('accepts bare JPK payload and bare JWS token', () {
|
|
final res = parseEParagonDetailed(fixture);
|
|
expect(res.receipt.items, isNotEmpty);
|
|
// Raw JWS from the wrapper should parse identically. Tolerate whitespace
|
|
// around the colon: the fixture is minified as the device emits it, but a
|
|
// pretty-printed payload is equally valid JSON and must not fail here.
|
|
final match = RegExp(r'"data"\s*:\s*"([^"]+)"').firstMatch(fixture);
|
|
expect(match, isNotNull, reason: 'fixture must carry a "data" JWS field');
|
|
final jws = match!.group(1)!;
|
|
final fromJws = parseEParagon(jws);
|
|
expect(fromJws.items.length, res.receipt.items.length);
|
|
});
|
|
|
|
test('rejects garbage input with a clear error', () {
|
|
expect(
|
|
() => parseEParagon('not json'),
|
|
throwsA(isA<EParagonParseException>()),
|
|
);
|
|
expect(
|
|
() => parseEParagon('{"foo": 1}'),
|
|
throwsA(isA<EParagonParseException>()),
|
|
);
|
|
});
|
|
}
|