Date: 2026-02-21 Scope: Full library — test coverage, ecosystem gaps, deployment readiness, performance Verdict: NOT READY for public release. Several blocking issues must be resolved first.
| Area | Status | Verdict |
|---|---|---|
| Test Coverage | Good for happy paths, significant gaps in error/edge cases | Important |
| Deployment Blockers | statecharts is a local path dep with no released artifact | CRITICAL |
| pom.xml Consistency | Fulcro version mismatch (deps.edn 3.9.3 vs pom.xml 3.7.0-RC3) | CRITICAL |
| Ecosystem Gaps | Rendering plugins need porting; demo is local-only | Important |
| Performance | No obvious problems; reasonable design | Acceptable |
| 43 Pre-existing Test Failures | Mock protocol incompatibilities in statechart specs | Important |
| Test File | Type | Tests | What It Covers |
|---|---|---|---|
form_statechart_spec.cljc | Tier 1 (pure chart) | ~20 | All form states, transitions, expression execution flags |
report_statechart_spec.cljc | Tier 1 (pure chart) | ~14 | All report states, pagination, sort/filter, cache resume |
form_statechart_test.cljc | Tier 2 (headless Fulcro) | 6 | Create, edit, attribute-change, cancel, save attempt, exit |
report_statechart_test.cljc | Tier 2 (headless Fulcro) | 7 | Auto-load, no-auto-load, manual run, failed load, pagination, row selection |
form_spec.cljc | Unit | 5 | Query generation, default state, find-fields, optional-fields, form-state init |
report_test.cljc | Unit | 2 | Initial state with fn/map initialize-ui-props, report helper fn |
session_spec.cljc | Unit | 5 | ident->session-id, session-id->ident, round-trips, auth-session-id |
headless_form_tests.clj | E2E (Datomic) | 8 | Edit existing, modify+save, cancel, subform, item edit, item save, invoice, sequential nav |
headless_routing_tests.clj | E2E (Datomic) | 10 | Initial startup, report click nav, form route-to!, sequential nav, dirty-form route guard, cancel route change, route-denied state |
headless_report_tests.clj | E2E (Datomic) | 3 | Inventory report load+filter, invoice report load, account invoices |
Container statechart — ZERO tests
container_chart.cljc has no Tier 1 spec (pure chart transitions)container_expressions.cljc has no Tier 2 tests (headless Fulcro)broadcast-to-children!, run-children-expr, resume-children-expr, unmount-children-expr are all untestedServer-paginated report — ZERO tests
server_paginated_report.cljc (259 lines) has no tests at any tierpage-cached? condition predicate untestedIncrementally-loaded report — ZERO tests
incrementally_loaded_report.cljc has no tests at any tierError conditions under-tested
on-save-failed-expr never tested with actual error extraction from mutation resultson-load-failed-expr expression logic not verified against real errorsConcurrent scenario testing — ZERO tests
Form expression edge cases
add-row-expr: tested in E2E only implicitly (subform existence check), never unit-testeddelete-row-expr: never tested at any tierderive-fields-ops: never tested (the derive-fields trigger mechanism)on-change trigger in attribute-changed-expr: never testedon-saved-expr with on-saved transaction: never testedleave-form-expr with cancel-route: never testedroute-denied-expr sync confirmation path: never tested (only async tested via E2E route guard)Report expression edge cases
postprocess-page-state: literally a no-op (TODO: Update post-process signature) — dead codereport-loaded callback: never invoked anywherebefore-load option: never testedraw-result-xform: never testedcompare-rows sort: never testedrow-visible? filter: only trivially tested (no-op filter in E2E)cache-expired?: never tested against real timingRouting edge cases
form-route-state exit-fn (abandon-form!): tested indirectly, never directly verifiedreport-route-state with param-keys: never testedback! and route-forward!: never testedcreate-test-app-with-url-sync) but never usedPer TRACKER.md: "MockEventQueue/MockExecutionModel protocol incompatibility in report/form statechart specs. Not related to Phase 3 — missing protocol method implementations in statecharts test mocks."
Assessment: These failures are in the statecharts library's test mocks, not in this project's tests. However:
statecharts testing API may be unstablestatecharts library before releaseThe headless plugin + test_helpers.cljc provides a reasonable foundation for users:
create-test-app / create-test-app-with-url-sync are well-documentedsettle! helper exists for non-immediate processingGap: No documentation or guide exists for "how to test your RAD statecharts app." Users would need to reverse-engineer the demo tests.
../fulcro-rad-datomic/ (confirmed via demo deps.edn :local/root)authorization.cljc provides a pass-through redact stub so fulcro-rad-datomic's resolver generators work without changes../fulcro-rad-semantic-ui/ (confirmed in directory listing)render-element multimethod replaces form-container-renderer/form-layout-rendererfr/render-field multimethod replaces install-field-renderer!rr/render-report multimethod replaces install-layout!../fulcro-rad-react-bootstrap/../fulcro-rad-demo/src/demo/ within this project. The standalone demo repo is NOT ported.| Project | Status | Impact |
|---|---|---|
fulcro-rad-sql | Exists at ../fulcro-rad-sql/ | Likely compatible (same resolver pattern as datomic) |
fulcro-rad-kvstore | Exists at ../fulcro-rad-kvstore/ | Likely compatible |
fulcro-rad-template | Exists at ../fulcro-rad-template/ | Needs full update for statecharts |
CLAUDE.md files scattered through the codebase are for AI agents, not human developers.;; deps.edn line 9
com.fulcrologic/statecharts {:local/root "../statecharts"}
The statecharts library is referenced as a local path, not a released Maven/Clojars artifact. The pom.xml lists it as:
<dependency>
<groupId>com.fulcrologic</groupId>
<artifactId>statecharts</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency>
The actual statecharts pom.xml shows version 1.4.0-RC2-SNAPSHOT. This is a release blocker:
0.1.0-SNAPSHOT) doesn't match the actual statecharts version (1.4.0-RC2-SNAPSHOT)| Dependency | deps.edn | pom.xml | Match? |
|---|---|---|---|
| Fulcro | 3.9.3 | 3.7.0-RC3 | NO |
| Clojure | 1.11.4 | 1.10.3 | NO |
| ClojureScript | 1.10.914 | 1.10.914 | Yes |
| Statecharts | local | 0.1.0-SNAPSHOT | NO (actual is 1.4.0-RC2-SNAPSHOT) |
| Timbre | 6.8.0 | 6.8.0 | Yes |
| Guardrails | 1.2.16 | 1.2.16 | Yes |
The pom.xml appears to be the pre-conversion pom.xml with outdated versions. This must be regenerated from deps.edn before release.
com.fulcrologic (correct)fulcro-rad-statecharts (new artifact name, not fulcro-rad)0.1.0-SNAPSHOT (appropriate for first release)a321576cebecc9230088b2c75fc0d45dfae9fb8d (should be dynamic):demo {:extra-deps {com.fulcrologic/fulcro-rad-datomic {:local/root "../fulcro-rad-datomic"}
...}
:override-deps {com.fulcrologic/fulcro-rad {:local/root "."}}}
This is acceptable for the demo alias (not shipped), but the :override-deps suggests that the old fulcro-rad artifact would conflict on the classpath. This needs documentation.
The CLAUDE.md notes: "malli (from statecharts dep chain) uses random-uuid (Clojure 1.11+). The routing ns cannot load in a 1.10.3 REPL."
scf/start!. This is comparable to uism/begin! — both create atoms/state.scf/send! processes events through the statechart engine. This involves:
ident->session-id uses string concatenation + keyword creation:
(keyword session-ns (str (namespace k) "_" (name k) "--" v))
session-id->ident uses string splitting + type parsing:
(str/split n #"--" 2) ;; then parse-id-value
Assessment: Both are O(1) string operations. No performance concern unless called in a tight loop (they aren't — called once per form/report lifecycle).
fops/load per form entity. Subform data is loaded via Fulcro's join resolution — no N+1.fops/load per report. Rows are batch-loaded via the source-attribute resolver.fops/apply-action which does swap! on the state atom. Multiple apply-action ops in a single expression result in multiple swaps. This is a minor inefficiency — could batch them — but not a blocking issue.The page cache in server_paginated_report.cljc stores pages as vectors in Fulcro state. For reports with many pages, this could accumulate memory. No cache eviction exists.
Assessment: Minor concern. Most reports won't exceed a handful of cached pages.
Release the statecharts library to Clojars — Without this, no downstream project can depend on fulcro-rad-statecharts. The local-path dependency is a complete deployment blocker.
Regenerate pom.xml from deps.edn — The Fulcro version mismatch (3.7.0-RC3 vs 3.9.3) and Clojure version (1.10.3 vs 1.11.4) will cause dependency resolution failures for consumers.
Update statecharts version in pom.xml — Change from 0.1.0-SNAPSHOT to whatever version the statecharts library is released at.
Add container statechart tests — At minimum, a Tier 1 spec testing state transitions and a Tier 2 test verifying child report coordination.
Add server-paginated report tests — This is a complex statechart variant with page caching that ships completely untested.
Port at least one rendering plugin — fulcro-rad-semantic-ui or fulcro-rad-react-bootstrap. Without a rendering plugin, the library is unusable for browser apps. The headless plugin only works for tests.
Write a migration guide — Document the changes from fulcro-rad to fulcro-rad-statecharts for existing users. Cover: removed namespaces, new defsc-form/defsc-report options, routing setup, rendering plugin conversion.
Fix sfr/edit! session targeting — Known issue: sends to form session instead of routing session. Documented in TRACKER.md but unfixed.
Resolve the 43 pre-existing test failures — Even though they're in the statecharts mocks, they affect user confidence and user test authoring.
Add concurrent scenario tests — Multiple forms open, form + report navigation.
Test error paths end-to-end — Save failure with actual server error, load failure with network error.
Remove dead code: postprocess-page-state is a no-op with a TODO. report-loaded callback is declared in options but never invoked.
Add URL sync tests — create-test-app-with-url-sync exists but is never used in any test.
Document the headless testing pattern — How users should structure their own tests using the test_helpers and headless plugin.
| Metric | Value | Target | Status |
|---|---|---|---|
| Unit test count | 83 | — | Good |
| Assertion count | 446 | — | Good |
| Test failures | 0 | 0 | Pass |
| Pre-existing failures | 43 | 0 | Fail |
| Form chart coverage | ~90% states/transitions | 100% | Good |
| Report chart coverage | ~90% states/transitions | 100% | Good |
| Container chart coverage | 0% | 100% | Fail |
| Server-paginated coverage | 0% | 100% | Fail |
| Incrementally-loaded coverage | 0% | 100% | Fail |
| Expression unit tests | ~40% | >80% | Needs Work |
| E2E integration | Good (3 test files) | — | Good |
| Rendering plugins ported | 0 / 2+ | >=1 | Fail |
| Documentation | 0 pages | Migration guide + README | Fail |
| Deployment readiness | Blocked | Releasable | Fail |
| Issue | Severity | Location | Status |
|---|---|---|---|
| Statecharts dep is local path | Critical | deps.edn:9 | Open |
| pom.xml version mismatches | Critical | pom.xml | Open |
| Container chart untested | Important | container_chart.cljc | Open |
| Server-paginated untested | Important | server_paginated_report.cljc | Open |
edit! wrong session target | Important | routing.cljc / form.cljc | Open (documented) |
postprocess-page-state no-op | Suggested | report_expressions.cljc:264-275 | Open |
report-loaded never called | Suggested | report_expressions.cljc:284 | Open |
| No rendering plugin | Important | — | Open |
| No user documentation | Important | — | Open |
| 43 mock test failures | Important | statecharts test mocks | Open (external) |
scf/current-configuration nil in headless Root | Important | Known issue per TRACKER | Open |
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |