Skip to content

Fix Flutter tests: remove codegen dependency for test compilation#5936

Merged
beastoin merged 14 commits intomainfrom
sora/fix-flutter-test-codegen-5935
Mar 23, 2026
Merged

Fix Flutter tests: remove codegen dependency for test compilation#5936
beastoin merged 14 commits intomainfrom
sora/fix-flutter-test-codegen-5935

Conversation

@beastoin
Copy link
Copy Markdown
Collaborator

Summary

  • Extract globalNavigatorKey from MyApp into app_globals.dart — 24 files that imported main.dart just for MyApp.navigatorKey now import the lightweight app_globals.dart instead
  • Remove dev_env.dart import from env.dart — breaks the transitive codegen chain so tests compile without build_runner
  • Fix 3 pre-existing env_test.dart failuresisUsingStagingApi tests expected true when stagingApiUrl was null, but the implementation explicitly requires it to be configured
  • Simplify test.sh — runs all tests via flutter test instead of listing 9 specific files (was missing 9 of 18 test files)
  • Replace broken widget_test.dart — the default Flutter template test constructed MyApp() directly, requiring full codegen

Before

flutter test → 12 compilation errors (Undefined name '_ProdEnv', '_DevEnv')
test.sh → runs 9 of 18 test files, 3 pre-existing assertion failures

After

flutter test → 183 tests, all passed (zero codegen dependency)
test.sh → runs all 18 test files, all pass

Test plan

  • flutter test passes with zero failures on a fresh worktree (no .g.dart files, no .env files)
  • test.sh still works (codegen bootstrap + full test run)
  • All 183 tests pass
  • MyApp.navigatorKey still works in main.dart (delegates to globalNavigatorKey)

Fixes #5935

🤖 Generated with Claude Code

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Mar 23, 2026

Greptile Summary

This PR eliminates the transitive codegen dependency that prevented flutter test from compiling on a clean checkout by introducing app_globals.dart, tightening Env.init(), and replacing the stale template widget test with a minimal smoke test.

Key changes:

  • app_globals.dart: Extracts globalNavigatorKey out of main.dart so the 24 files that needed the navigator key can avoid importing main.dart's heavy codegen chain (firebase_options_*.dart, envied-generated classes). MyApp.navigatorKey now delegates to it via a getter, preserving backward compatibility across the whole codebase.
  • env/env.dart: Removes the import 'package:omi/env/dev_env.dart' that dragged _DevEnv (a codegen class) into every indirect importer; Env.init() now requires an explicit EnvFields argument (all existing call-sites already pass one).
  • test.sh: Collapses 9 hard-coded file paths into a single flutter test, ensuring all 18 test files run.
  • env_test.dart: Updates three isUsingStagingApi tests to match the existing implementation's behaviour (staging banner requires STAGING_API_URL to be explicitly configured). The removed tests expected isTrue against a null stub which was never reachable by the new implementation.
  • test_env.dart: Adds a public TestEnv stub — currently unused by any test file (see inline comment).
  • widget_test.dart: Replaces the wrong Flutter template counter-app test with a trivial MaterialApp smoke test that compiles without codegen.

Confidence Score: 5/5

  • Safe to merge — all runtime behaviour is preserved and the refactor is mechanical import-swap across 24 files.
  • The core change (extract globalNavigatorKey, remove codegen import from env.dart) is a clean, well-scoped refactor with no logic changes at runtime. MyApp.navigatorKey still works identically via the delegating getter. The only open items are two P2 style suggestions: test_env.dart is unused dead code, and isUsingStagingApi has no positive-case test coverage. Neither affects production correctness or reliability.
  • app/test/test_env.dart (unused) and app/test/unit/env_test.dart (missing positive coverage for isUsingStagingApi)

Important Files Changed

Filename Overview
app/lib/app_globals.dart New file that extracts globalNavigatorKey from MyApp to break the transitive import chain on main.dart — clean, minimal, well-commented.
app/lib/env/env.dart Removes dev_env.dart import and tightens init() to require a parameter, breaking the transitive codegen chain. All existing callers already pass a parameter so no breakage.
app/lib/main.dart Imports app_globals.dart and converts MyApp.navigatorKey from a static final field to a static get delegating to globalNavigatorKey, preserving full backward compatibility.
app/test/test_env.dart Introduces a public TestEnv stub, but it is not imported or used by any test file in the PR — dead code, though harmless.
app/test/unit/env_test.dart Updates tests to match the already-changed isUsingStagingApi implementation (requires explicit stagingApiUrl). Removes all three tests that expected isTrue, leaving no coverage for the true code-path of isUsingStagingApi.
app/test/widget_test.dart Replaces the stale Flutter template counter test (wrong for this app) with a minimal MaterialApp smoke test that compiles without codegen.
app/test.sh Simplified from listing 9 specific test files to a single flutter test, now running all 18 test files automatically.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["main.dart\n(Env.init, MyApp)"] -->|imports| B["app_globals.dart\nglobalNavigatorKey"]
    A -->|imports| C["env/dev_env.dart\n(codegen)"]
    A -->|imports| D["env/prod_env.dart\n(codegen)"]

    E["providers/*.dart\nservices/*.dart\nutils/*.dart"] -->|Before: imported main.dart| A
    E -->|After: import app_globals.dart| B

    F["test files"] -->|Before: imported main.dart → codegen chain| A
    F -->|After: import app_globals.dart only| B

    G["env.dart\ninit(EnvFields)"] -->|Before: default to DevEnv| C
    G -->|After: required param, no import| H["No codegen dependency"]

    style B fill:#d4edda,stroke:#28a745
    style H fill:#d4edda,stroke:#28a745
    style C fill:#fff3cd,stroke:#ffc107
    style D fill:#fff3cd,stroke:#ffc107
Loading

Reviews (1): Last reviewed commit: "Update pubspec.lock with transitive depe..." | Re-trigger Greptile

Comment thread app/test/test_env.dart Outdated
Comment on lines +4 to +29
class TestEnv implements EnvFields {
@override
String? get openAIAPIKey => null;
@override
String? get mixpanelProjectToken => null;
@override
String? get apiBaseUrl => 'https://api.omiapi.com/';
@override
String? get growthbookApiKey => null;
@override
String? get googleMapsApiKey => null;
@override
String? get intercomAppId => null;
@override
String? get intercomIOSApiKey => null;
@override
String? get intercomAndroidApiKey => null;
@override
String? get googleClientId => null;
@override
String? get googleClientSecret => null;
@override
bool? get useWebAuth => false;
@override
bool? get useAuthCustomToken => false;
@override
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 TestEnv is never imported or used

test_env.dart adds a public TestEnv stub, but no test file in the repository imports it. env_test.dart defines its own private _TestEnvFields, and capture_provider_test.dart does not use Env at all.

If the intent is to provide a shared stub for future tests, the file is fine to keep — but it should be imported at least by one test (env_test.dart could replace its inline _TestEnvFields with it). Otherwise this is dead code that can be removed to keep the test/ directory tidy.

Comment on lines 50 to 70
group('Env.isUsingStagingApi', () {
// Note: _TestEnvFields.stagingApiUrl returns null, which means
// STAGING_API_URL is not explicitly configured. The implementation
// requires explicit configuration to return true.
test('false when override points to non-staging URL', () {
Env.overrideApiBaseUrl('https://api.prod.example.com/');
expect(Env.isUsingStagingApi, isFalse);
});

test('true when override equals stagingApiUrl', () {
test('false when stagingApiUrl is not explicitly configured (null)', () {
// Even though the override matches the fallback staging URL,
// isUsingStagingApi requires _instance.stagingApiUrl to be non-null.
Env.overrideApiBaseUrl('https://api.omiapi.com/');
expect(Env.isUsingStagingApi, isTrue);
});

test('true when override equals stagingApiUrl with trailing slash', () {
Env.overrideApiBaseUrl('https://api.omiapi.com');
expect(Env.isUsingStagingApi, isTrue);
expect(Env.isUsingStagingApi, isFalse);
});

test('false when override differs from stagingApiUrl', () {
test('false when override differs from fallback', () {
Env.overrideApiBaseUrl('https://something-else.example.com/');
expect(Env.isUsingStagingApi, isFalse);
});

test('true with case-insensitive and whitespace-trimmed URL', () {
Env.overrideApiBaseUrl(' HTTPS://API.OMIAPI.COM/ ');
expect(Env.isUsingStagingApi, isTrue);
});
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 No positive (isTrue) coverage for isUsingStagingApi

All three removed tests tested the true-returning path. The updated test group now only verifies that isUsingStagingApi returns false in three different ways, leaving the true branch (_normalizeUrl(effective) == _normalizeUrl(configuredStagingUrl)) and the URL-normalisation logic (case folding, trailing-slash stripping) completely uncovered.

Consider adding a variant of _TestEnvFields with an explicit stagingApiUrl:

class _StagingTestEnvFields extends _TestEnvFields {
  @override
  String? get stagingApiUrl => 'https://api.omiapi.com/';
}

and then exercising the cases that were previously tested:

test('true when override matches explicitly configured stagingApiUrl', () {
  // Uses a separate Env instance — or exercise via a helper
  // that accepts an EnvFields to call _normalizeUrl comparison directly
});

This is especially useful because the _normalizeUrl helper (case-insensitive, trailing-slash trimming) is still present and still needs to be exercised to catch regressions.

beastoin and others added 14 commits March 23, 2026 06:30
Breaks the transitive dependency on main.dart so that tests and
providers no longer pull in codegen-dependent env files.

Fixes #5935

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
env.dart imported dev_env.dart only to provide a DevEnv() default in
Env.init(). Since main.dart always passes the instance explicitly,
the default was unused. Removing it breaks the transitive codegen
dependency so tests compile without build_runner.

Fixes #5935

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
MyApp.navigatorKey is now a getter that delegates to the extracted
globalNavigatorKey. Backward-compatible — callers using MyApp.navigatorKey
continue to work, but new code should import app_globals.dart directly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace import of main.dart with app_globals.dart in all 10 provider
files. Uses globalNavigatorKey directly instead of MyApp.navigatorKey.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace import of main.dart with app_globals.dart in device_connection
and 5 notification handler files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace import of main.dart with app_globals.dart in page providers,
alert utilities, and audio player utils.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The original template test constructed MyApp() directly, which requires
all codegen files to exist. Replace with a minimal MaterialApp test.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…torKey

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The tests expected isUsingStagingApi=true when override URL matched the
fallback staging URL, but the implementation requires stagingApiUrl to be
explicitly configured (non-null) in the EnvFields instance. Updated tests
to match this intentional behavior.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
test.sh ran only 9 of 18 test files individually. Replace with a single
'flutter test' invocation that discovers and runs all tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
No test file imports it — env_test.dart uses its own _TestEnvFields.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Exercises the isTrue path and URL normalisation (case folding,
trailing-slash stripping) using an EnvFields stub with explicit
stagingApiUrl. Separate file required because Env._instance is
late final (one init per process).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@beastoin beastoin force-pushed the sora/fix-flutter-test-codegen-5935 branch from 0f707dd to 73199e6 Compare March 23, 2026 06:30
@beastoin
Copy link
Copy Markdown
Collaborator Author

lgtm

@beastoin beastoin merged commit 442cce8 into main Mar 23, 2026
2 checks passed
@beastoin beastoin deleted the sora/fix-flutter-test-codegen-5935 branch March 23, 2026 07:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Flutter tests fail without codegen: env.dart transitively requires build_runner

1 participant