Status: backlog Priority: P1 Created: 2026-02-18 Owner: conductor
ui_routes.cljc is the statechart-driven routing system for Fulcro — the highest-value integration point. It has ~30 public/internal functions but only ~6 are directly tested. Existing tests cover happy-path routing and URL sync well, but miss many behavioral branches, edge cases, and entire function groups.
Current test files:
ui_routes_test.cljc — Pure statechart tests: has-routes?, leaf-route?, route entry/exit, busy guard, force-continueurl_sync_headless_spec.cljc — Full Fulcro app: programmatic nav, back/forward, restoration, cleanuproute_url_test.cljc — URL parsing: url->route-target, current-url-pathroute_url_history_spec.cljc — SimulatedURLHistory protocol implementationroute-to-event-name — qualified-keyword, component class, qualified-symbol inputs?! — fn argument invoked, non-fn returned, component class NOT invokedreachable-targets — chart with targets + reachable sets, empty chart, deduplicationform? / rad-report? — component detectioninitialize-route! — :once vs :always strategies, form defaults to :always, report defaults to :once, initial-props callback, event-data passthrough for forms, ident extractionestablish-route-params-node — params filtering by :route/params set, empty paramsbusy-form-handler — dirty form returns true, clean form false, missing form falsecheck-component-busy? — custom ro/busy? fn, form fallback, no busy fndeep-busy? — recursive walk through child sessions, seen set prevents infinite loops, multi-level nestingroute-denied? — returns true when :routing-info/open active, false when idleabandon-route-change! — closes modal, stays on current route (complement to existing force tests)istate — child chart invocation, srcexpr resolution (statechart-id vs co-located chart), actor setuproutes cross-transitions — Transition 1: enter owner + store pending route; Transition 2: forward to child session::pending-child-route passthrough from parent to child on entrysend-to-self! — walks parent chain to find nearest co-located child chart, sends event; no-op when no ancestor has a child sessioncurrent-invocation-configuration — walks parent chain to find nearest co-located child chart, returns child config; nil when none foundreplace-join! — parallel join-key vs :ui/current-route, parent without ident errorupdate-parent-query! — parallel vs sequential delegationurl-sync-on-save — child session walks parent chain to find root handler, caches in child-to-rootsrc/main/com/fulcrologic/statecharts/integration/fulcro/ui_routes.cljc — Primary source (898 lines)src/main/com/fulcrologic/statecharts/integration/fulcro/route_url.cljc — URL utilitiessrc/test/com/fulcrologic/statecharts/integration/fulcro/ui_routes_test.cljc — Extend with slices 1-4src/test/com/fulcrologic/statecharts/integration/fulcro/url_sync_headless_spec.cljc — Extend with slices 5-8Slices 1-4 use new-testing-env (no Fulcro app needed). Slices 5-8 require a headless Fulcro app fixture like url_sync_headless_spec.cljc already provides. Each slice is independently implementable and verifiable.
Priority order: Slices 1, 2, 3, 4 first (pure/easy). Then 5 (highest value). Then 6, 7, 8.
route-to-event-name tested with 3 input typesinitialize-route! tested with :once/:always/form/report branchesdeep-busy? tested with 2+ levels of nestingabandon-route-change! tested as complement to force-continuesend-to-self! tested with and without active child sessionurl-sync-on-save child→root delegation testedCan 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 |