Skip to content

Unit and template tests#35

Merged
Arjun544 merged 13 commits into
mainfrom
unit-and-template-tests
May 5, 2026
Merged

Unit and template tests#35
Arjun544 merged 13 commits into
mainfrom
unit-and-template-tests

Conversation

@Arjun544
Copy link
Copy Markdown
Owner

@Arjun544 Arjun544 commented May 5, 2026

Summary by CodeRabbit

  • New Features

    • Custom font upload capability: Users can now drag-and-drop custom fonts in the theme configuration step, which are bundled into generated Flutter projects
    • Fonts are validated for file type and size before inclusion
  • Bug Fixes

    • Improved conditional template rendering and dependency management
    • Enhanced type safety for icon handling and ScreenUtil integration
  • Documentation

    • Added comprehensive testing guide documenting validation strategy and CI/CD pipeline
  • Tests

    • Implemented tiered testing infrastructure for quality assurance

@vercel
Copy link
Copy Markdown

vercel Bot commented May 5, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
flutter-init Ready Ready Preview, Comment May 5, 2026 7:55am

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 5, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 57db29bf-5215-41b8-9614-8a274e6a53d0

📥 Commits

Reviewing files that changed from the base of the PR and between bf38516 and 634c213.

⛔ Files ignored due to path filters (2)
  • bun.lock is excluded by !**/*.lock
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (78)
  • .github/workflows/test-tier1.yml
  • .github/workflows/test-tier2.yml
  • .github/workflows/test-tier3.yml
  • .gitignore
  • CONTRIBUTING.md
  • README.md
  • app/api/generate/route.ts
  • app/components/wizard/WizardShell.tsx
  • app/components/wizard/steps/BackendStep.tsx
  • app/components/wizard/steps/ThemeStep.tsx
  • app/lib/config/schema.ts
  • app/lib/generator/handlebars.ts
  • app/lib/generator/index.ts
  • app/lib/state/useWizardStore.tsx
  • components/ui/select.tsx
  • docs/testing.md
  • package.json
  • scripts/validate-dart.ts
  • templates/flutter/base/lib/main.dart.hbs
  • templates/flutter/base/lib/src/config/app_config.dart.hbs
  • templates/flutter/base/lib/src/imports/core_imports.dart.hbs
  • templates/flutter/base/lib/src/imports/packages_imports.dart.hbs
  • templates/flutter/base/lib/src/routing/app_router.dart.hbs
  • templates/flutter/base/lib/src/services/services.dart.hbs
  • templates/flutter/base/lib/src/shared/widgets/app_button.dart.hbs
  • templates/flutter/base/lib/src/shared/widgets/app_card.dart.hbs
  • templates/flutter/base/lib/src/shared/widgets/app_empty_state.dart.hbs
  • templates/flutter/base/lib/src/shared/widgets/app_icon.dart.hbs
  • templates/flutter/base/lib/src/shared/widgets/app_loading.dart.hbs
  • templates/flutter/base/lib/src/shared/widgets/app_top_bar.dart.hbs
  • templates/flutter/base/lib/src/shared/widgets/common_image.dart.hbs
  • templates/flutter/base/lib/src/shared/wrappers/(isRiverpod,isProvider,isBloc,isGetX,isMobX)@state_wrapper.dart.hbs
  • templates/flutter/base/lib/src/shared/wrappers/(supportsLocalization)@localization_wrapper.dart.hbs
  • templates/flutter/base/lib/src/shared/wrappers/(usesScreenutil)@screen_util_wrapper.dart.hbs
  • templates/flutter/base/lib/src/shared/wrappers/(usesSkeletonizer)@skeleton_wrapper.dart.hbs
  • templates/flutter/base/lib/src/shared/wrappers/session_listener_wrapper.dart.hbs
  • templates/flutter/base/lib/src/theme/text_theme.dart.hbs
  • templates/flutter/base/lib/src/theme/theme.dart.hbs
  • templates/flutter/base/pubspec.yaml.hbs
  • templates/flutter/base/test/widget_test.dart.hbs
  • templates/flutter/overlays/architecture/layer-first/lib/src/presentation/providers/(isNoneState)@auth_view_model.dart.hbs
  • templates/flutter/overlays/backend/appwrite/lib/src/services/(usesAppwriteAuth)@auth_service.dart.hbs
  • templates/flutter/overlays/backend/custom/lib/src/services/auth_service.dart.hbs
  • templates/flutter/overlays/extras/dotenv/.env.hbs
  • templates/flutter/partials/features/auth/auth_logic.hbs
  • templates/flutter/partials/features/auth/forgot_password_screen.hbs
  • templates/flutter/partials/features/auth/login_screen.hbs
  • templates/flutter/partials/features/auth/session_provider.hbs
  • templates/flutter/partials/features/auth/signup_screen.hbs
  • templates/flutter/partials/features/home/home_page.hbs
  • templates/flutter/partials/features/onboarding/onboarding_page.hbs
  • tests/e2e/dart-validation.spec.ts
  • tests/e2e/run-matrix.ts
  • tests/e2e/validate-combo.ts
  • tests/generator.spec.ts
  • tests/integration/full-pipeline.spec.ts
  • tests/integration/overlay-composition.spec.ts
  • tests/reporters/failed-tests-reporter.ts
  • tests/unit/backend.spec.ts
  • tests/unit/handlebars-helpers.spec.ts
  • tests/unit/matrix-shard-1.spec.ts
  • tests/unit/matrix-shard-2.spec.ts
  • tests/unit/matrix-shard-3.spec.ts
  • tests/unit/matrix-shard-4.spec.ts
  • tests/unit/misc-flags.spec.ts
  • tests/unit/navigation.spec.ts
  • tests/unit/state-management.spec.ts
  • tests/unit/theme.spec.ts
  • tests/utils/assertions.ts
  • tests/utils/combinations.ts
  • tests/utils/config-builder.ts
  • tests/utils/critical-combos.ts
  • tests/utils/generate.ts
  • tests/utils/matrix-tests.ts
  • tests/utils/matrix.config.ts
  • tests/utils/misc-profiles.ts
  • vitest.config.ts
  • vitest.e2e.config.ts

📝 Walkthrough

Walkthrough

This PR introduces a comprehensive three-tier testing infrastructure with custom font file support. Changes include new GitHub Actions workflows for layered CI validation (Layer 1 unit/integration, Layer 2 critical Dart validation, Layer 3 full matrix), test utilities and Dart project validators, custom font upload/configuration in the wizard and schema, multipart form-data request handling for font files, and numerous template refinements for router generation, conditional imports, ScreenUtil sizing, and context lifecycle safety in async flows.

Changes

Testing Infrastructure & CI/CD

Layer / File(s) Summary
CI/CD Workflow Definition
.github/workflows/test-tier*.yml, .gitignore
Three new GitHub Actions workflows define tiered test runs: Tier 1 (Layer 1 unit/integration on every push), Tier 2 (critical Layer 2 Dart validation on PR to main), Tier 3 (full matrix with concurrency-based chunking pre-release). Added test-artifact and generator-output entries to .gitignore.
Test Orchestration Scripts
scripts/validate-dart.ts, tests/e2e/run-matrix.ts, tests/e2e/validate-combo.ts
Bun/Node scripts implement per-combo validation: validate-dart.ts runs critical combos with Dart analysis; run-matrix.ts orchestrates test execution and failure reporting; validate-combo.ts validates a single combo by generating, running dart pub get, conditionally running build_runner, and executing dart analyze --fatal-infos.
Vitest Configuration & Reporters
vitest.config.ts, vitest.e2e.config.ts, tests/reporters/failed-tests-reporter.ts
Base Vitest config excludes e2e tests by default, sets timeouts (60s/30s), enables parallel execution, and adds a custom reporter. Dedicated e2e config with 120s timeout, Node environment, and path alias. FailedTestsReporter collects failing tests and writes to tests/results/layer1/failed-tests.log.
Test Utilities & Matrix Configuration
tests/utils/matrix.config.ts, tests/utils/combinations.ts, tests/utils/critical-combos.ts, tests/utils/misc-profiles.ts, tests/utils/config-builder.ts, tests/utils/generate.ts, tests/utils/assertions.ts, tests/utils/matrix-tests.ts
Core test utilities: matrix.config.ts defines architecture/state/backend/navigation option arrays and generates 375 PRIMARY_COMBINATIONS; combinations.ts implements Cartesian product generation; critical-combos.ts defines 24 hand-curated Layer 2 test configurations; misc-profiles.ts provides reusable misc feature-flag presets; config-builder.ts builds full ScaffoldConfig from combos; generate.ts wraps scaffold generation for in-memory and disk output; assertions.ts provides 13+ assertion helpers (token detection, empty-file checks, pubspec parsing, dependency assertions, architecture validation, file content checks).
Unit & Integration Tests
tests/unit/matrix-shard-*.spec.ts, tests/unit/handlebars-helpers.spec.ts, tests/unit/backend.spec.ts, tests/unit/navigation.spec.ts, tests/unit/state-management.spec.ts, tests/unit/theme.spec.ts, tests/unit/misc-flags.spec.ts, tests/integration/full-pipeline.spec.ts, tests/integration/overlay-composition.spec.ts, tests/e2e/dart-validation.spec.ts
Layer 1 tests split the 375-combo matrix across 4 shards; specialized unit tests validate Handlebars helpers, backend dependencies, navigation packages, state-management overlays, theme generation, and misc flags. Integration tests validate full pipeline correctness and overlay composition. E2E tests run Dart analysis on critical combos when Dart SDK is available.
Documentation & Manifest
docs/testing.md, CONTRIBUTING.md, README.md, package.json
docs/testing.md defines the two-layer validation strategy, CI tiering, and release checklist. CONTRIBUTING.md adds a pre-submission test gate requirement. README.md links the testing guide. package.json adds test:layer1/2/3, test:unit/integration, and test:preflight scripts; bumps vitest to ^4.1.5 and adds @vitest/ui, bun-types, yaml.

Custom Font Support

Layer / File(s) Summary
Configuration Schema
app/lib/config/schema.ts
Introduces font-related constants (SUPPORTED_FONT_EXTENSIONS, FONT_MAX_SIZE_BYTES), Zod schemas for FontStyle/FontWeight, deriveFontFamily() helper to normalize filenames into family names, and CustomFontEntry schema/type. Extends ThemeConfig with customFonts: CustomFontEntry[] and updates MiscConfig.usesDotenv to boolean (instead of literal).
Wizard Store & Font File Management
app/lib/state/useWizardStore.tsx, app/components/wizard/steps/ThemeStep.tsx
Store adds in-memory fontFiles: Map<string, File> to track binary blobs (never persisted), plus addFontFile/removeFontFile/clearFontFiles callbacks. Persisted config explicitly clears theme.customFonts to avoid stale metadata. ThemeStep adds font file drag-and-drop, file input selection, validation (extension/size), metadata derivation, and UI rendering with FontCard components and a non-persistence warning.
API & File Upload
app/api/generate/route.ts, app/components/wizard/WizardShell.tsx
API endpoint switches from JSON to multipart/form-data: parses "config" field (JSON string), collects "font" field entries as File[], passes both to generateFlutterScaffold(config, fontEntries). WizardShell builds the multipart request by appending config and one "font" field per dropped file (keyed by fileName), with improved JSON error parsing on non-OK responses.
Generator & Template Context
app/lib/generator/index.ts
generateFlutterScaffold(input, fontEntries) now writes each uploaded font file to assets/fonts/ before zipping. buildTemplateContext groups custom fonts by family to emit fontFamilies (with fileName/style/weight per font) and selects the first family as primaryFontFamily. Template context extended with hasCustomFonts, primaryFontFamily, and fontFamilies flags.
Template Updates for Font Rendering
templates/flutter/base/pubspec.yaml.hbs, templates/flutter/base/lib/src/theme/text_theme.dart.hbs, templates/flutter/base/lib/src/theme/theme.dart.hbs, templates/flutter/overlays/extras/dotenv/.env.hbs
pubspec.yaml conditionally includes assets/fonts/ and emits a fonts: section with family/asset/weight/style metadata from flags.fontFamilies. text_theme.dart applies custom font family via baseTextTheme.apply(fontFamily: ...) when hasCustomFonts is true. theme.dart sets fontFamily in ThemeData and multiple CupertinoTextThemeData text styles. New .env.hbs template conditionally includes Firebase/Supabase/Appwrite config blocks and API base URL based on backend/http flags.

Template & Codebase Refinements

Layer / File(s) Summary
Router & Code Generation
templates/flutter/base/lib/src/routing/app_router.dart.hbs, templates/flutter/base/pubspec.yaml.hbs
auto_route router switches from hand-written RootStackRouter with pagesMap/RouteConfig to @AutoRouterConfig() annotation with generated app_router.gr.dart imports and List<AutoRoute> page references. pubspec.yaml bumps auto_route to ^11.1.0 and auto_route_generator to ^10.5.0, adds dependency_overrides: {test_api: 0.7.6} for Riverpod.
Import/Export Optimization
templates/flutter/base/lib/src/imports/core_imports.dart.hbs, templates/flutter/base/lib/src/imports/packages_imports.dart.hbs, templates/flutter/base/lib/src/services/services.dart.hbs, templates/flutter/base/lib/src/config/app_config.dart.hbs, templates/flutter/partials/features/auth/session_provider.hbs
Conditional imports: flutter_native_splash export gated by usesFlutterNativeSplash; core_imports import in app_config gated by usesDio; http_service export gated by (usesHttp && !usesDio). Riverpod/Bloc/MobX/Provider branches in packages_imports hide conflicting symbols (describeIdentity/shortHash from Riverpod, version/StringExtension from MobX, Cupertino transitions from auto_route, MultipartFile/Response from http when Dio is enabled). session_provider imports imports.dart instead of packages_imports.
Lifecycle Safety & Context Mounting
templates/flutter/partials/features/auth/auth_logic.hbs, templates/flutter/partials/features/auth/login_screen.hbs, templates/flutter/partials/features/auth/signup_screen.hbs, templates/flutter/partials/features/auth/forgot_password_screen.hbs
Auth flow error/success toast notifications now guarded by context.mounted (or event.context.mounted for Bloc) to prevent late-lifecycle widget updates. Navigation and state cleanup in catch/finally blocks also respect context.mounted.
State Management Typing
templates/flutter/base/lib/src/shared/wrappers/(isRiverpod,isProvider,isBloc,isGetX,isMobX)@state_wrapper.dart.hbs
Session provider declarations explicitly typed: ChangeNotifierProvider<SessionProvider>, BlocProvider<SessionBloc>, Provider<SessionStore>.
ScreenUtil & Responsive Sizing
templates/flutter/base/lib/src/shared/widgets/app_button.dart.hbs, templates/flutter/base/lib/src/shared/widgets/app_card.dart.hbs, templates/flutter/base/lib/src/shared/widgets/app_empty_state.dart.hbs, templates/flutter/base/lib/src/shared/widgets/app_icon.dart.hbs, templates/flutter/base/lib/src/shared/widgets/app_loading.dart.hbs, templates/flutter/base/lib/src/shared/widgets/app_top_bar.dart.hbs, templates/flutter/base/lib/src/shared/widgets/common_image.dart.hbs, templates/flutter/partials/features/onboarding/onboarding_page.hbs
Dimension calculations (padding, sizing, spacing) switch from fixed numeric values to ScreenUtil-scaled expressions ({{res ...}}/.w/.h) when usesScreenutil is enabled. Conditional spacers use AppSpacing.* constants or fixed pixels based on flag. AppIcon now restricts input to IconData and removes HugeIcon fallback logic.
Wrapper & Partial Refactoring
templates/flutter/base/lib/src/shared/wrappers/(supportsLocalization)@localization_wrapper.dart.hbs, templates/flutter/base/lib/src/shared/wrappers/(usesScreenutil)@screen_util_wrapper.dart.hbs, templates/flutter/base/lib/src/shared/wrappers/session_listener_wrapper.dart.hbs, templates/flutter/base/lib/src/theme/text_theme.dart.hbs, templates/flutter/base/lib/main.dart.hbs, templates/flutter/base/test/widget_test.dart.hbs, templates/flutter/overlays/architecture/layer-first/lib/src/presentation/providers/(isNoneState)@auth_view_model.dart.hbs
LocalizationWrapper now unconditionally generates EasyLocalization instead of returning child when disabled. ScreenUtilWrapper is always generated (conditional removed). session_listener_wrapper imports packages_imports only for non-NoneState. main.dart conditionally assigns WidgetsFlutterBinding result to widgetsBinding (used by FlutterNativeSplash.preserve) only when splash is enabled. Widget test setup of SharedPreferences mock is now guarded by usesSharedPreferences in addition to supportsLocalization. auth_view_model overlay includes auth_logic partial. Pubspec state-dependency versions bumped (flutter_hooks^0.21.3+1, flutter_riverpod^3.2.1, hooks_riverpod^3.2.1 conditionally). flutter_dotenv is now conditional on usesDotenv instead of always included.
Handlebars Helper & Backend Updates
app/lib/generator/handlebars.ts, templates/flutter/overlays/backend/appwrite/lib/src/services/(usesAppwriteAuth)@auth_service.dart.hbs, templates/flutter/overlays/backend/custom/lib/src/services/auth_service.dart.hbs, templates/flutter/partials/features/auth/session_provider.hbs, templates/flutter/partials/features/auth/forgot_password_screen.hbs, templates/flutter/partials/features/home/home_page.hbs, components/ui/select.tsx
res Handlebars helper now returns String(value) when usesScreenutil is false (instead of conditionally appending .0). Appwrite auth service removes unused models import and stops storing session result. Custom backend Dio calls now use typed generics (post<Map<String, dynamic>>, get<Map<String, dynamic>>, post<void>) instead of manual casting. MobX store base renamed SessionStoreBase with mixin-based SessionStore declaration. HomePage logic refactored so GetX/MobX read user inside reactive wrappers instead of outside. Subtitle conditions simplified to user != null && user.name != null. Select trigger/item styling adds font-normal Tailwind utility. Backend step label styling changed from font-semibold to font-medium.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Wizard as Wizard UI
    participant API as /api/generate
    participant Generator as Generator
    participant Templates as Templates

    User->>Wizard: Drop font files + configure
    Wizard->>Wizard: Validate files (extension, size)
    Wizard->>Wizard: Store File blobs in-memory<br/>(fontFiles Map)
    User->>Wizard: Click Generate
    Wizard->>API: POST multipart/form-data<br/>(config + font Files)
    API->>API: Parse config field (JSON)
    API->>API: Collect font field entries
    API->>Generator: generateFlutterScaffold(config, fonts)
    Generator->>Generator: Build template context<br/>(group fonts by family)
    Generator->>Templates: Render with flags<br/>(hasCustomFonts,<br/>primaryFontFamily,<br/>fontFamilies)
    Templates->>Generator: Generated pubspec.yaml<br/>(fonts: section)
    Templates->>Generator: Generated theme.dart<br/>(fontFamily applied)
    Generator->>Generator: Write fonts to assets/fonts/
    Generator->>Generator: Create ZIP
    API->>User: ZIP download
Loading
sequenceDiagram
    participant CI as GitHub Actions
    participant L1 as Layer 1<br/>(Unit+Integration)
    participant L2 as Layer 2<br/>(Dart Validation)
    participant L3 as Layer 3<br/>(Full Matrix)
    participant TestUtils as Test Utilities
    participant Generator as Project Generator
    participant DartSDK as Dart SDK

    CI->>L1: Trigger on every push
    L1->>TestUtils: Load PRIMARY_COMBINATIONS (375)
    TestUtils->>Generator: Generate per combo (in-memory)
    L1->>TestUtils: Run assertions<br/>(tokens, files, deps)
    L1-->>CI: Pass/Fail Layer 1
    
    CI->>L2: Trigger on PR to main
    L2->>TestUtils: Load CRITICAL_COMBOS (24)
    TestUtils->>Generator: Generate per combo (to disk)
    Generator->>DartSDK: Run dart pub get
    Generator->>DartSDK: Conditionally run build_runner
    Generator->>DartSDK: Run dart analyze --fatal-infos
    L2-->>CI: Collect pass/fail + logs
    
    CI->>L3: Trigger on main push
    L3->>TestUtils: Split combos into chunks<br/>(by concurrency param)
    TestUtils->>Generator: Generate chunk range<br/>(parallel jobs)
    Generator->>DartSDK: Validate each combo
    L3-->>CI: Gate on L1+L2 success
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • Arjun544/flutter_init#9: Modifies the same Flutter template files for main initialization and native splash handling.
  • Arjun544/flutter_init#27: Updates the res Handlebars helper logic in app/lib/generator/handlebars.ts for ScreenUtil value stringification.

Poem

🐰 A warren of tests now runs with care,
Fonts bundled up and rendered fair,
The router sings with routes auto-built,
Templates shimmer, guilt-free of tilt!
Three tiers tall, the pipeline stands proud—
Quality checked before the crowd.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch unit-and-template-tests

@Arjun544 Arjun544 merged commit 6cde10e into main May 5, 2026
7 of 8 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request May 22, 2026
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.

1 participant