mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-10 20:07:04 +01:00
billsplit had never produced an Android APK. file_picker 11.0.3 — the latest release on pub.dev — is wedged under AGP 9 in both directions: it skips applying the Kotlin Gradle Plugin when AGP >= 9, so with built-in Kotlin off its own Kotlin never compiles (`cannot find symbol: FilePickerPlugin`), and with built-in Kotlin on its buildscript leaks KGP onto the global classpath via rootProject.allprojects, which AGP then rejects for every module. The app's Gradle config was never at fault: android/app/build.gradle.kts and settings.gradle.kts are byte-identical to habit_stack, home_inventory and diet_guard_app, which all build. Only the dependency differed, so the fix is the dependency — the toolchain stays on the house-standard AGP 9. Ported both call sites to the official file_selector. Its save flow returns a destination and leaves the write to the caller, where file_picker wrote the bytes inside the plugin; that write now goes through an injectable seam because a real dart:io future never completes inside testWidgets' fake-async zone, so a widget test could otherwise never observe the resulting snackbar. The test double moves from a MethodChannel mock to a FileSelectorPlatform fake (file_selector speaks Pigeon, so a channel mock would not intercept it), and a plain non-widget test covers the real on-disk writer to hold 100% coverage without an ignore. The launcher icon is now verified from the built artifact: the ic_launcher assets unzipped from the APK render as the charcoal + gold perforated receipt, not the stock Flutter beach. Peak build footprint is 1.86 GiB, inside budget. Also rewrites ci_mirror.sh to run its gates in a disposable worktree at HEAD. `pre-commit run --all-files` stashes the live tree, and in a shared checkout that made an unrelated agent's uncommitted work collide with hook auto-fixes, failing the push while blaming an innocent hook — and putting that work inside a stash window, which memories/git-rules.md forbids. A clean worktree needs no stash and is a truer mirror of CI, which never sees a dirty file. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
57 lines
1.9 KiB
Dart
57 lines
1.9 KiB
Dart
import 'dart:io';
|
|
import 'dart:typed_data';
|
|
|
|
import 'package:billsplit/domain/models.dart';
|
|
import 'package:billsplit/domain/xlsx_export.dart';
|
|
import 'package:billsplit/ui/receipt_screen.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
void main() {
|
|
test('export handles no store/paid, unassigned items and non-drinkers', () {
|
|
final people = [
|
|
Person(id: 'a', name: 'Ala'),
|
|
Person(id: 'b', name: 'Bob', drinks: false),
|
|
];
|
|
final receipt = Receipt(
|
|
id: 'r',
|
|
title: 'Manual',
|
|
participantIds: {'a', 'b'},
|
|
items: [
|
|
Item(id: 'i1', name: 'Bread', totalGr: 500),
|
|
Item(
|
|
id: 'i2',
|
|
name: 'Beer',
|
|
totalGr: 300,
|
|
category: Categories.alcohol,
|
|
assignment: Assignment(mode: AssignMode.drinkers),
|
|
),
|
|
Item(
|
|
id: 'i3',
|
|
name: 'Ghost',
|
|
totalGr: 100,
|
|
assignment: Assignment(mode: AssignMode.custom),
|
|
),
|
|
],
|
|
);
|
|
final bytes = exportXlsx(receipt: receipt, roster: people, groups: []);
|
|
expect(bytes.length, greaterThan(1000));
|
|
expect(bytes[0], 0x50);
|
|
});
|
|
|
|
// Exercises the REAL disk writer, deliberately as a plain `test` rather than
|
|
// a `testWidgets`: a real dart:io future never completes inside the
|
|
// fake-async zone, which is the whole reason the export flow writes through
|
|
// an injectable seam.
|
|
test('the real export writer puts the bytes on disk', () async {
|
|
final dir = Directory.systemTemp.createTempSync('billsplit_export');
|
|
addTearDown(() => dir.deleteSync(recursive: true));
|
|
final target = '${dir.path}/split.xlsx';
|
|
final payload = Uint8List.fromList([0x50, 0x4B, 0x03, 0x04, 0x99]);
|
|
|
|
debugSetExportWriter(null); // restore the real writer
|
|
await writeExport(target, payload, 'application/vnd.ms-excel');
|
|
|
|
expect(File(target).readAsBytesSync(), payload);
|
|
});
|
|
}
|