mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-02 11:07:10 +00:00
* test(folio): replace tautological properties with 4 domain invariants Drop properties that can't fail (e.g. List.size >= 0, balances are Long integers) or that just check the extractor itself (account_count equals accounts.length). Keep auth routing liveness, error-clear liveness, and reachability goals. Add four properties that target the real code paths: - balanceMatchesTransactionDelta: a new ledger row shifts the balance by exactly its signed amount (credit +, debit -). - totalEqualsSumOfAccounts: home total equals sum of per-account balances at every state, not only on home. - balanceChangeRequiresActiveAccount: an account's balance can only change while that account is the active one in the navigator. - duplicateAccountNamesRejected: account names are unique under the app's actual dedup rule (case-insensitive after trim). * chore(folio): upgrade sdk-android to io.github.priyanshujain.sanderling:0.0.1-rc4 Group id moved from io.github.priyanshujain to io.github.priyanshujain.sanderling in the rc4 publish. * chore(folio): pin @sanderling/spec to 0.0.1-rc4
Folio
A minimal Kotlin Multiplatform personal-ledger app: login with demo credentials, create accounts, add credits and debits. Shared UI across Android, iOS, and Web via Compose Multiplatform. Doubles as the example sanderling runs its property-based specs against.
Stack
- Kotlin Multiplatform + Compose Multiplatform (shared UI)
- kotlinx.serialization for file-backed persistence
- kotlinx.coroutines for state flows
- sanderling
sdk-androidfor harness integration on Android
Prerequisites
just- JDK 17
- Android SDK (auto-discovered under
$ANDROID_HOME,~/Library/Android/sdk, or the Homebrew cask) - Xcode 16+ and
xcodegen(brew install xcodegen) for iOS
Android
just install # build + install on a booted emulator / device
just uninstall
just clean
iOS
just ios # default device: iPhone 17 Pro
IOS_DEVICE="iPhone 15" just ios # pick a different simulator
just ios regenerates iosApp/iosApp.xcodeproj from iosApp/project.yml,
builds the KMP framework, links it into the SwiftUI host, installs, and
launches.
Demo credentials
email: [email protected]
password: ledger123
Run a sanderling test (Android)
just test
If no device is connected, sanderling boots the single AVD it finds. With multiple AVDs, pick one:
AVD=Pixel_7 just test
Persistent settings can live in .env alongside the justfile:
AVD=Pixel_7
DURATION=5m
Traces land in ./sanderling/runs/<timestamp>/.
How it connects to sanderling
composeApp/src/androidMain/.../FolioApplication.ktcallsSanderling.start(this)and registers snapshot extractors (logged_in,account_count,total_balance,route)sanderling/spec.tsimports@sanderling/spec, reads those snapshots, asserts properties, and weights the actions the fuzzer picks fromjust testinvokessanderling testagainst the installed APK