From 77d4dcbc38e21d87f5098fd02ef6068911b6d8fd Mon Sep 17 00:00:00 2001 From: Shroominic <34897716+shroominic@users.noreply.github.com> Date: Tue, 23 Jun 2026 19:24:44 +0800 Subject: [PATCH] feat(app): OG_DEMO flag to run demo driver on native builds for simulator testing Add a compile-time OG_DEMO build flag (--dart-define=OG_DEMO=true) so native/simulator builds run the in-memory DemoCgmDriver instead of the real BLE Aidex driver, and auto-scan + auto-connect on launch so the app lands directly on the populated dashboard. The iOS simulator has no Bluetooth, so this unblocks simulator-based feature verification. When the flag is false (the default), behavior is unchanged: production builds keep using the real AidexSensorDriver and the manual scan flow. Co-Authored-By: Claude Opus 4.8 --- openhealth/lib/main.dart | 28 +++++++++++++++++++++++ openhealth/lib/src/driver_factory_io.dart | 11 +++++++++ openhealth/test/og_demo_flag_test.dart | 23 +++++++++++++++++++ 3 files changed, 62 insertions(+) create mode 100644 openhealth/test/og_demo_flag_test.dart diff --git a/openhealth/lib/main.dart b/openhealth/lib/main.dart index 5e83274..79c0d60 100644 --- a/openhealth/lib/main.dart +++ b/openhealth/lib/main.dart @@ -12,6 +12,12 @@ import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:shared_preferences/shared_preferences.dart'; +/// When built with `--dart-define=OG_DEMO=true`, the app runs the in-memory +/// demo driver (see [buildDefaultDriver]) and auto-connects on launch so it +/// lands directly on the populated dashboard — used for simulator/feature +/// verification. Defaults to false; production builds are unaffected. +const bool kOgDemo = bool.fromEnvironment('OG_DEMO', defaultValue: false); + Future main() async { WidgetsFlutterBinding.ensureInitialized(); @@ -35,9 +41,31 @@ Future _bootstrap() async { driver: buildDefaultDriver(), ); await controller.initialize(); + if (kOgDemo) { + // In demo mode (simulator/feature verification) the demo driver only + // surfaces its sensor after a scan, so auto-scan and auto-connect to land + // directly on the populated dashboard. Strictly gated behind OG_DEMO and + // skipped when a previous session was already restored from preferences. + unawaited(_autoConnectDemoSensor(controller)); + } return controller; } +/// Scans with the demo driver and connects to the first discovered sensor so +/// OG_DEMO builds open straight onto the populated dashboard. +Future _autoConnectDemoSensor(CgmAppController controller) async { + if (controller.snapshot != null) { + // A persisted session is already (re)connecting; don't interfere. + return; + } + await controller.scan(); + final sensors = controller.sensors; + if (sensors.isEmpty) { + return; + } + await controller.connect(sensors.first); +} + class _BootstrapApp extends StatefulWidget { const _BootstrapApp(); diff --git a/openhealth/lib/src/driver_factory_io.dart b/openhealth/lib/src/driver_factory_io.dart index 082a6c9..ab0f92d 100644 --- a/openhealth/lib/src/driver_factory_io.dart +++ b/openhealth/lib/src/driver_factory_io.dart @@ -2,6 +2,17 @@ import 'package:cgm_aidex/cgm_aidex.dart'; import 'package:cgm_ble_flutter/cgm_ble_flutter.dart'; import 'package:cgm_core/cgm_core.dart'; +import 'demo_driver.dart'; + +/// When built with `--dart-define=OG_DEMO=true`, native/simulator builds use the +/// in-memory [DemoCgmDriver] instead of the real BLE driver, so the app can be +/// exercised in the iOS simulator (which has no Bluetooth). Defaults to false, +/// so production builds are unchanged and keep using the real Aidex driver. +const bool kOgDemo = bool.fromEnvironment('OG_DEMO', defaultValue: false); + CgmDriver buildPlatformDriver() { + if (kOgDemo) { + return DemoCgmDriver(); + } return AidexSensorDriver(const FlutterBluePlusTransport()); } diff --git a/openhealth/test/og_demo_flag_test.dart b/openhealth/test/og_demo_flag_test.dart new file mode 100644 index 0000000..ac56312 --- /dev/null +++ b/openhealth/test/og_demo_flag_test.dart @@ -0,0 +1,23 @@ +import 'package:cgm_aidex/cgm_aidex.dart'; +import 'package:cgm_core/cgm_core.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:openglucose/src/demo_driver.dart'; +import 'package:openglucose/src/driver_factory_io.dart'; + +void main() { + group('OG_DEMO driver selection', () { + test('selects DemoCgmDriver when OG_DEMO is set, real driver otherwise', () { + final CgmDriver driver = buildPlatformDriver(); + + // `kOgDemo` is a compile-time constant from --dart-define=OG_DEMO. + // Run with `flutter test --dart-define=OG_DEMO=true` to exercise the + // demo branch; without the define, production behavior is asserted. + if (kOgDemo) { + expect(driver, isA()); + } else { + expect(driver, isA()); + expect(driver, isNot(isA())); + } + }); + }); +}