feat(poc/bridge): add flutter_rust_bridge hello spike
Proof-of-concept proving the Flutter/Rust bridge exit criterion from docs/architecture/proof-of-concept-plan.md §2: "Flutter can call Rust and receive event stream data." The spike exposes one synchronous fallible command (greet) returning a typed GreetResult / GreetError DTO, and one async event stream (counter_stream) emitting typed CounterTick events. The Flutter app demonstrates both flows on a Material 3 surface; the headless test suite in test/poc_verification_test.dart exercises the same API directly through dart:ffi. Verified on 2026-05-13 (Linux desktop, Flutter 3.41.9 / Dart 3.11.5, flutter_rust_bridge 2.12.0, Rust 1.95). All three tests pass: - greet() returns typed result for valid input - greet() surfaces typed error for empty input - counterStream() delivers the expected event sequence Authority: PoC plan §2, DEC-014 (typed Flutter/Rust bridge), SAD-068, SDD-079, SysDes-049. Naming note: the PoC plan lists this as flutter-rust-bridge-hello, but Dart pubspec.yaml package names require underscores; the directory uses underscores accordingly. Not product code; not promoted into chanora_bridge. Layout note: includes the full Flutter platform scaffold (android, ios, macos, windows, web, linux). Only the Linux desktop target has been built and verified.
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
// Chanora PoC verification — flutter_rust_bridge_hello.
|
||||
//
|
||||
// Verifies the PoC exit criterion from
|
||||
// `docs/architecture/proof-of-concept-plan.md` §2:
|
||||
// "Flutter can call Rust and receive event stream data."
|
||||
//
|
||||
// This is a Flutter integration test (runs on a real Flutter engine on the
|
||||
// Linux desktop target). It exercises the FRB-generated Dart API directly
|
||||
// rather than driving the demo UI — that is sufficient evidence for the
|
||||
// PoC exit criterion and is robust against future UI changes.
|
||||
|
||||
import 'package:flutter_rust_bridge_hello/src/rust/api/simple.dart';
|
||||
import 'package:flutter_rust_bridge_hello/src/rust/frb_generated.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
setUpAll(() async => await RustLib.init());
|
||||
|
||||
group('Chanora FRB hello PoC', () {
|
||||
test('greet() returns typed result for valid input', () {
|
||||
final r = greet(name: 'Chanora');
|
||||
expect(r.message, contains('Hello, Chanora!'));
|
||||
// Sanity-check the typed numeric field round-trips.
|
||||
expect(r.elapsedMicros, isA<BigInt>());
|
||||
expect(r.elapsedMicros.toInt(), greaterThanOrEqualTo(0));
|
||||
});
|
||||
|
||||
test('greet() surfaces typed error for empty input', () {
|
||||
// FRB maps the Rust `Err(GreetError { .. })` to a Dart exception.
|
||||
expect(() => greet(name: ' '), throwsA(isA<GreetError>()));
|
||||
});
|
||||
|
||||
test('counterStream() delivers the expected event sequence', () async {
|
||||
const count = 4;
|
||||
final events = <CounterTick>[];
|
||||
await for (final tick in counterStream(count: count, intervalMs: 50)) {
|
||||
events.add(tick);
|
||||
}
|
||||
expect(events, hasLength(count));
|
||||
for (var i = 0; i < count; i++) {
|
||||
expect(events[i].seq.toInt(), i);
|
||||
expect(events[i].note, 'tick $i/$count');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user