โ† Core
In the workslicense: BSD-3-Clause

tom_flutter_form_test

tom_flutter_form_test ยท v1.0.0+1

A two-tab Flutter demo and test app for the form framework: tom_flutter_ui forms and fields over the kernel's resources, security and reflection, exercised end-to-end against the live Flutter engine. See its demo catalogue.

See License
Status
In the works
LOC
353.5k
Tests
449
Test LOC
11.0k

Overview

From the module readme.md file:

What it enables

Enables Live form reference, End-to-end form tests.

Relationships

Standalone โ€” no declared relationships.

Tom Flutter Form Test

A Flutter demo application for the Tom Form Framework โ€” the form widgets and field system from tom_flutter_ui, driven by the resource, security, and reflection facilities of tom_core_kernel.

It is a runnable showcase (not a published package โ€” publish_to: none) used to exercise the form stack end to end. The showcase is the visible half; the other half is the gate under test/, which drives the same screens and is where a regression in the stack is actually caught. See Tests.

What it demonstrates

The app opens on a two-tab shell (RootScreen):

Demos tab

The Demos tab lists 33 demos in ten sections. doc/demo_catalogue.md uses the same ten headings and maps each demo to the tom_flutter_ui or kernel feature it validates; test/demo_catalogue_sections_test.dart holds the two to the same headings and the same demos under each.

  • Phase 1 โ€” Spec-aligned demos (Demo Aโ€“Demo D): form lifecycle

(bind / save / discard, pristine behaviour) with sync / async / cross-field validation and error banners, authorization & events, nested forms & theming, and hide-on-authorization. - Phase 2 โ€” Extended field flavours (Demo Eโ€“Demo H): selection and boolean variants, complex breakpoint and authorization scenarios. - Phase 2a โ€” Collections & master-detail (Demo H-Aโ€“H-E): the master-detail, expandable-row, editable-table and customer-form patterns. - Phase 3 โ€” Numeric, date/time & duration fields (Demo I, Demo J). - Phase 4 โ€” Enum, object, file & nullable fields (Demo K, Demo L): enum / object / lookup, files and nullable variants. - Phase 5a โ€” Cupertino string + bool + selection (Demo M): Material and Cupertino fields side by side. - Phase 5b โ€” Cupertino numeric + date/time (Demo N). - Phase 5c โ€” Cupertino search/lookup/file + family swap (Demo O, Demo P): Cupertino search, lookup and file fields, and the family swap on a breakpoint. - Phase 6 โ€” Non-form custom widgets (Demo Q, Demo R): auth / empty / overlay, and tree / radio / infinite-scroll selection. - Supporting reference demos (Demo 1โ€“Demo 10): basic and nested forms, authorization, validation, settings, field-layout options, error placement, breakpoints, the preset showcase, and central JSON-driven styling.

Examples tab

Stripped-down, copy-friendly sample code under lib/examples/ โ€” the same patterns as the demos but reduced to the minimum needed to read and reuse (customer forms, master-detail, expandable rows, editable tables, read-only variants, plus shared scaffolding/resources/authorization helpers).

This tab is the package's examples; there is no example/ directory and no doc/api/. The package is an application with no importable surface: an example/ program would have nothing to import, and an API summary would have no API to describe. The workspace examples and API-summary guidelines exempt such packages. The five samples, each in a Material and a Cupertino flavour, are documented one by one in doc/demo_catalogue.md and driven by example_smoke_test.dart, example_interaction_test.dart and example_screenshot_test.dart.

How to run

flutter pub get

# Reflection glue (lib/main.reflection.dart) is generated and committed.
# Only regenerate it when reflected type signatures change:
./reflection_generation.sh   # wraps `dart run tom_reflection_generator --nested`
                             # set DART=/path/to/dart if dart is not on PATH

flutter run                  # on any configured device/emulator
flutter test                 # the gate โ€” see Tests below

On startup the app loads assets/demo_resources.json, merges in the Examples section's resource keys, registers them with TomTextResourceProvider, and initializes reflection before runApp.

Tests

flutter test

flutter test runs 66 gating suites, every one of them a *_test.dart file under test/:

KindSuitesWhat they cover
Demo interaction tests 24 Mount one demo or example screen and drive it, asserting that screen's own behaviour โ€” including validator and debounce behaviour, and overflow-free layout at several viewport sizes
Smoke tests 10 That every screen of a phase โ€” and, for widget_test.dart , the demo list itself โ€” builds and reaches a settled frame. No behaviour beyond "it mounts"
Blanket exception sweep 1 One case per demo tile: boot the app, scroll the tile into view, tap it, and fail if any framework error fired
Regression guards 13 One reported defect each, pinned so it cannot come back. The file's opening dartdoc names the report it belongs to
Behaviour matrices 2 One case per cell of a matrix documented elsewhere, so the table and the behaviour cannot drift apart
Widget-family coverage 1 The list-form widgets driven directly rather than through a demo screen
Golden screenshots 3 Rendered pixels against the committed baselines under test/goldens/ โ€” the five numbered demos, the Examples section, and the โ‰ฅ1600 px bordered band. These are why test/fonts/ is checked in
Source invariants 4 That the committed lib/main.reflection.dart still covers the sources it mirrors, that every formId / listId literal in lib/ is a usable scope id, and that the demo catalogue and this README group the demos exactly as the Demos tab does
Unit tests8Arithmetic and mapping, with no widget tree

Those figures are gated by tom_ai/core/tool/check_test_inventories.py, which holds every kind, their sum, and the total against the directory itself โ€” so a suite added or deleted without touching this table fails the build. The table names no filenames on purpose: sixty-six of them would be the longest section of this README and still a worse list than test/, which is exact by construction. What the counts buy is the one thing the directory cannot say about itself, which is that its population is the one somebody wrote down.

Every file under test/ ends in _test.dart, singular. flutter test discovers **_test.dart only, so a plural _tests.dart name is matched by nothing and reported by nothing โ€” that is not hypothetical here, and it is why the gate above exists. Three files under test/ are helpers rather than suites and are excluded by that same rule: flutter_test_config.dart (the per-suite harness config Flutter loads automatically), support/test_fonts.dart and support/form_id_sites.dart. A test whose golden is compared must await loadTestFonts() in setUpAll, after reflection is initialized and the resource provider registered.

The run is deliberately parallel โ€” do not add -j 1. Serial runs were once required here on the ground that parallel isolates would corrupt process-global state: the resource bundle, the authorization adapter, the reflection registry the forms build. They cannot. flutter test gives every suite file its own flutter_tester process, so each file's registrations are its own, and no suite here opens a socket, writes a file or reaches a database, so there is nothing outside the process to contend for either. Dropping the flag runs the whole suite green in about half the time.

Project layout

PathContents
lib/main.dartApp entry point, resource bootstrap, two-tab shell
lib/main.reflection.dart Generated reflection registration, seeded from lib/main.dart (do not hand-edit)
lib/demos/The Demos-tab catalogue (one file per demo)
lib/examples/The Examples-tab stripped-down samples
lib/forms/Form definitions shared across demos
lib/panels/Reusable panel widgets
lib/state/Application/demo state objects
lib/actions/Form action handlers
lib/common/Shared helpers
assets/demo_resources.jsonText resources consumed by the demos
test/ The gating suites, plus the goldens/ , fonts/ and support/ they need
doc/demo_catalogue.md Demo/example โ†’ upstream feature map and launch guide

License

BSD 3-Clause licensed โ€” see LICENSE.

License
BSD 3-Clause License

Copyright (c) 2024-2026, Peter Nicolai Alexis Kyaw
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its
   contributors may be used to endorse or promote products derived from
   this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.